程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 基於DOS的多任務系統實現教程

基於DOS的多任務系統實現教程

編輯:關於C語言
 

-操作系統作業- = =
主要有線程的創建和撤銷、線程的調度、線程的阻塞和喚醒、線程的同步與互斥、利用消息緩沖隊列通信機制實現線程間通信這幾塊。

代碼如下:turboc2下測試通過


code#include
/*#include */
#include
#include
#include

#define NTCB 5 /*最多任務數*/
#define TC 2 /*定義時間片長度*/
#define NBUF 6 /*定義緩沖區大小*/
#define NTEXT 20

/*狀態碼常量定義*/
#define FINISHED 0
#define RUNNING 1
#define READY 2
#define BLOCKED 3

/*INDOS標志*/
#define GET_INDOS 0x34
#define GET_CRIT_ERR 0x5d06

char far *indos_ptr = 0;/*存放INDOS標志的地址*/
char far *crit_err_ptr = 0; /*存放嚴重錯誤標志的地址*/

/*全局變量*/
int n=0;
int current =0;
int timecount = 0;
int TL = 10;

 


typedef int(far *codeptr)(void);

typedef struct
{
int value;
struct TCB *wq;

}semaphore;

semaphore mutexfb={1,NULL};/* buf[] is a critical resource */
semaphore sfb={NBUF,NULL};/* buf[] */
semaphore mutex={1,NULL};
semaphore sa={1,NULL},sb={0,NULL};

struct TCB{
unsigned char *stack; /*線程堆棧的其實地址*/
unsigned ss; /*堆棧段制*/
unsigned sp; /*堆棧指針*/
char state; /*堆棧狀態,取值為狀態符*/
char name[10]; /*線程外部標識符*/
struct buffer *mq;
semaphore mutex;
semaphore sm;
struct TCB *next;
} tcb[NTCB];

struct int_regs{
unsigned bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags,off,seg;
};

 

struct buffer {
int id;
int size;
char text[NTEXT];
struct buffer *next;
} buf[NBUF],*freebuf;

 

int InitTcb();
int create(char *name,codeptr code,int stck);
void destory(int id);
void interrupt swtch(void);
void interrupt new_int8(void);
void over();
int all_finished(void);
void InitDos(void);
int DosBusy(void);
void interrupt (*old_int8)(void);
void block(struct TCB **qp);
void wakeup(struct TCB **qp);
void p(semaphore *sem);
void v(semaphore *sem);
void wait(int delay);
void send(char *receiver,char *a,int size);
int receive(char *sender,char *b);
void init_main();


int InitTcb() /*初始化tcb*/
{
int i;
for(i=0;iip = FP_OFF(code);
pp->cs = FP_SEG(code);
pp->ds = _DS;
pp->es = _DS;
pp->flags = 0x200;/*flags寄存器 存放中斷變量地址*/
pp->off=FP_OFF(over); /*執行over函數*/
pp->seg=FP_SEG(over);
tcb[id].state = READY;
/*for(i=0;i<10;i++)
{
tcb[id].name[i] = *name;
if((++name) == '\0');
break;
}
tcb[id].name[9] = '\0';*/
strcpy(tcb[id].name,name);
enable();
printf("thread pid = %d,name = %s craeted\n",id,name);
return(1);

}
void destory(int id)
{
disable();
free(tcb[id].stack);
tcb[id].stack = NULL;
tcb[id].state = FINISHED;
tcb[id].name[0] = '\0';
printf("\n_______thread %d destory______\n",id);
enable();

}


void over() /*函數執行結束的銷毀線程*/
{
destory(current);
swtch();
printf("____now n = %d\n____",n );
}

int all_finished(void)
{
int i=1;
for(i=1;idosx(&regs,&regs,&segregs);/*intdosx();調用DOs的INIT21H中斷*/
indos_ptr = MK_FP(segregs.es,regs.x.bx);/*取實際地址*/


if(_osmajor<3)
crit_err_ptr=indos_ptr+1; /*嚴重錯誤在INDOS後一字節處*/
else if(_osmajor==3&&_osmajor==0)
crit_err_ptr=indos_ptr-1; /*嚴重錯誤在INDOS前一字節處*/
else
{
regs.x.ax=GET_CRIT_ERR;
intdosx(&regs,&regs,&segregs);
crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
}
}/*初始化DOS,取得INDOS標志和嚴重錯誤標志地址*/

 

int DosBusy(void)/*1 busy,0 not busy,-1 not call*/
{
if(indos_ptr&&crit_err_ptr)
return(*indos_ptr||*crit_err_ptr);
else
return (-1);

}
void block(struct TCB **qp) /*阻塞*/
{
int id;
struct TCB *tcbp;
id=current;
tcb[id].state=BLOCKED;

disable();
if((*qp)==NULL)
(*qp)=&tcb[id];
else
{
tcbp=*qp;
while(tcbp->next!=NULL)
tcbp=tcbp->next;
tcbp->next=&tcb[id];
}
tcb[id].next=NULL;
swtch();
enable();

 


}
void wakeup(struct TCB **qp) /*喚醒*/
{
int i;
struct TCB *tcbv;

disable();
if((*qp)==NULL) return;
tcbv=(*qp);
(*qp)=(*qp)->next;
tcbv->state=READY;
tcbv->next=NULL;
enable();

 

}

void p(semaphore *sem)
{
struct TCB **qp;

disable();
sem->value = sem->value-1;
if(sem->value<0)
{
qp = &(sem->wq);
block(qp);
}
enable();
}


void v(semaphore *sem)
{
struct TCB **qp;

disable();
qp = &(sem->wq);
sem->value=sem->value+1;
if(sem->value<=0)
wakeup(qp);
enable();
}
void wait(int delay)
{long i,j,k;
for(i=0;inext;
return(buff);
}

void insert(struct buffer **mq,struct buffer *buff)
{ struct buffer *temp;

if(buff==NULL) return;
buff->next=NULL;
if(*mq==NULL)
*mq=buff;
else{
temp=*mq;
while(temp->next!=NULL)
temp=temp->next;
temp->next=buff;
}
}

struct buffer *remov(struct buffer **mq,int sender)
{
struct buffer *p,*q,*buff;
q=NULL;
p=*mq;
while((p->id!=sender)&&(p->next!=NULL)){
q=p;
p=p->next;
}
if(p->id==sender){
buff=p;
if(q==NULL) *mq=buff->next;
else q->next=buff->next;
buff->next=NULL;
return(buff);
} else {
return(NULL);
}
}

void send(char *receiver,char *a,int size)
{
struct buffer *buff;
int i,id=-1;

disable();

for(i=0;iid=current;
buff->size=size;
buff->next=NULL;
for(i=0;isize;i++,a++)
buff->text[i]=*a;

/*p(&tcb[id].mutex);*/
insert(&(tcb[id].mq),buff);
/*v(&tcb[id].mutex);*/
v(&tcb[id].sm);

enable();
}

int receive(char *sender,char *b)
{
int i,size,id=-1;
struct buffer *buff;

disable();

for(i=0;isize;
for(i=0;isize;i++,b++)
*b=buff->text[i];
p(&mutexfb);
insert(&freebuf,buff);
v(&mutexfb);
v(&sfb);

enable();
return(size);
}

 


void f1(void)
{ long i,j,k;
for(i=0;i<1000;i++)
{
putchar('a');
for(j=0;j<1000;j++)
for(k=0;k<100;k++);
}
}

void f2(void)
{ long i,j,k;
for(i=0;i<100;i++)
{
putchar('b');
for(j=0;j<1000;j++)
for(k=0;k<100;k++);
}
}

void f3(void)
{ long i,j,k;
int temp;
for(i=0;i<100;i++){
temp=n;
wait(5);
temp++;
n=temp;
for(j=0;j<1000;j++)
for(k=0;k<99;k++);
}
}

void f4(void)
{ long i,j,k;
int temp;

for(i=0;i<100;i++){
temp=n;
temp++;
wait(10);
n=temp;
for(j=0;j<1000;j++)
for(k=0;k<100;k++);
}
}


void f5(void)
{ long i,j,k;
int temp;
for(i=0;i<5;i++){
p(&mutex);
temp=n;
wait(100);
temp++;
n=temp;
v(&mutex);
printf("[F5]now n = %d\n",n);
for(j=0;j<1000;j++)
for(k=0;k<99;k++);
}
}

void f6(void)
{ long i,j,k;
int temp;

for(i=0;i<5;i++){
p(&mutex);
temp=n;
temp++;
wait(200);
n=temp;
v(&mutex);
printf("[F6]now n = %d\n",n);
for(j=0;j<1000;j++)
for(k=0;k<100;k++);
}
}

void f7(void)
{ long i,j,k;
int temp;
for(i=0;i<5;i++)
{
p(&sa);
temp=n;
temp++;
wait(300);
n=temp;
v(&sb);
printf("[3]%d\n",n );
}

}
void f8(void)
{ long i,j,k;
int temp;
for(i=0;i<5;i++)
{
p(&sb);
temp=n;
temp++;
wait(100);
n=temp;
v(&sa);
printf("[4]%d\n",n );
}

}

void sender(void)
{
int i,j;
char a[10];
loop:
for(i=0;i<10;i++){
strcpy(a,"message");
a[7]='0'+n;
a[8]=0;
send("receiver",a,strlen(a));
printf("sender:Message \"%s\" has been sent\n",a);
n++;
}
receive("receiver",a);
if (strcmp(a,"ok")!=0){
printf("Not be committed,Message should be resended!\n");/*接收進程沒確認,需重新發送消息*/
goto loop;
}else printf("Committed,Communication is finished!\n");/*發送者得到接收者的確認,通信結束*/
}

void receiver(void)
{
int i,j,size;
char b[10];
for(i=0;i<10;i++){
b[0]=0;
while((size=receive("sender",b))==-1);
printf("receiver: Message is received--");/*已接收到消息--*/
for(j=0;j7) ;
switch(sele){
case 1:
create("f1",(codeptr)f1,1024);
create("f2",(codeptr)f2,1024);
/*clrscr();*/
printf("\t No deprivation in two threads' concurrent running: \n");/*不剝奪方式下兩個線索的並發執行*/
printf("\t Thread f1 continuous output \'a\' 1000 times ;\n");/*其中線索f1不斷輸出字母a,共1000次*/
printf("\t Thread f2 continuous output \'b\' 1000 times 。\n");/*而線索f2不斷輸出字母b,共100次*/
printf("\t Press any key to continue!\n");/*按任意鍵繼續*/
getch();
break;

case 2:
create("f1",(codeptr)f1,1024);
create("f2",(codeptr)f2,1024);
/*clrscr();*/
printf("\t Round-Robin in two threads' concurrent running:\n");/*時間片輪轉方式下兩個線索的並發執行*/
printf("\t Thread f1 continuous output \'a\' 1000 times ;\n");/*其中線索f1不斷輸出字母a,共1000次*/
printf("\t Thread f2 continuous output \'b\' 1000 times 。\n");/*而線索f2不斷輸出字母b,共100次。*/
printf("\t Please configurate the length of time slice(1/18.2):");/*請設置時間片的大小(單位為1/18.2秒)*/
scanf("%d",&TL);
printf("\t Press any key to continue!\n");
getch();
setvect(8,new_int8);
break;

case 3:
n=0;
create("f3",(codeptr)f3,1024);
create("f4",(codeptr)f4,1024);
/*clrscr();*/
printf("\t Threads share critical resource(no mutual exclusion).\n");/* 線索同時共享臨界資源的情況*/
printf("\t Thread f3 and f4 share the same variable parameter \'n\';\n");/*線索f3和f4共享一變量n*/
printf("\t Thread f3 continuous add 1 to \'n\' 100 times;\n"); /*times線索f3不斷對n進行加1操作,共進行100次*/
printf("\t Thread f4 also continuous add 1 to \'n\' 100 times;\n");/*線索f4也不斷對n進行加1操作,共進行100次*/
printf("\t Result should be 200.\n");/*因此,最後n的值應為200*/
printf("\t Press any key to continue!\n");
getch();
TL=1;
setvect(8,new_int8);
break;

case 4:
n=0;
create("f5",(codeptr)f5,1024);
create("f6",(codeptr)f6,1024);
clrscr();
printf("\t Threads share critical resource(in mutual exclusion): \n");/*線索互斥共享臨界資源*/
printf("\t Thread f3 and f4 share the same variable parameter \'n\';\n");/*線索f3和f4共享一變量n*/
printf("\t Thread f3 continuous add 1 to \'n\' 100 times;\n");/*線索f3不斷對n進行加1操作,共進行100次*/
printf("\t Thread f4 also continuous add 1 to \'n\' 100 times;\n");/*線索f4也不斷對n進行加1操作,共進行100次*/
printf("\t Result should be 200.\n");/*因此,最後n的值應為200*/
TL=1;
printf("\t Press any key to continue!\n");
getch();
setvect(8,new_int8);
break;
case 5:
n=0;
create("iop",(codeptr)f7,1024);
create("cp",(codeptr)f8,1024);
clrscr();
printf("\t Computing process and Output process concurrently running wihtout synchronism: \n");/*沒同步的計算進程和輸出進程的並發執行*/
printf("\t Computing process \'cp\' continuous calculate and put the result into a buffer,\n");/*並將其放入一緩沖區*/
printf("\t Printing process \'iop\' orderly fetch \'cp\' and output it.\n");/*打印進程iop依次取出cp放入緩沖區中的數,將它輸出出來*/
printf("\t Here ,\'cp\' computed 10 results:0,1,2,3,4,5,6,7,8,9\n");/*本例中,cp計算出十個數,分別為0,1,2,3,4,5,6,7,8,9*/
printf("\t Press any key to continue!\n");
getch();
TL=1;
setvect(8,new_int8);
break;
case 6:
n=0;
create("f7",(codeptr)f7,1024);
create("f8",(codeptr)f8,1024);
clrscr();
printf("\t Computing process and Output process concurrently running in synchronism: \n");/*經過同步的計算進程和輸出進程的並發執行:*/
printf("\t Computing process \'cp\' continuous calculate and put the result into a buffer,\n\n");/*計算進程cp不斷計算數,並將其放入一緩沖區,*/
printf("\t Printing process \'iop\' orderly fetch \'cp\' and output it.\n");/*打印進程iop依次取出cp放入緩沖區中的數,將它輸出出來.*/
printf("\t Here ,\'cp\' computed 10 results:0,1,2,3,4,5,6,7,8,9\n");/*本例中,cp計算出十個數,分別為0,1,2,3,4,5,6,7,8,9\n*/
printf("\t Press any key to continue!\n");
getch();
TL=1;
setvect(8,new_int8);
break;
case 7:
init_buf();
n=0;
create("sender",(codeptr)sender,1024);
create("receiver",(codeptr)receiver,1024);
clrscr();
printf("\t Communication among threads:\n");/*線索間的通信: */
printf("\t Thread \'sender\' call primitive(send) to send 10 messages to \'receiver\';\n");/*線索sender調用send原語向線索receiver發送十個消息*/
printf("\t The 10 messages are:message0,...,message9;\n");/*十個消息的內容分別為*/
printf("\t Thread \'receiver\' call primitive(receive) to receiver message from \'sender\';\n");/*線索receiver調用receive接收sender發來的消息*/
printf("\t Here, message buffer has 5 units.\n");/*本例中,消息緩沖的個數為5個*/
printf("\t Press any key to continue!\n");/*按任意鍵繼續!\n");*/
getch();
TL=1;
setvect(8,new_int8);
break;

default:sele=0;
}
while(!all_finished());
if(sele==3){
printf(" The result of no mutual exclusion in shared critical resource:\n");/*因對臨界資源的共享沒互斥,本次運行的結果為*/
printf("n==%d\n",n);
}
if(sele==4)
printf("n==%d\n",n);
if(sele!=0){
printf("All of the threads are terminated expect \'0\',press any key to quit system!\n");/*除0號線索外,其余線索都已執行完畢,請按任意鍵結束! ;*/
getch();
}
setvect(8,old_int8);
}
printf("\t\tThe multi-task system is terminated\n");/*多任務系統結束運行*/

}

 

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved