实验一基于dos的多任务系统实现.docx
《实验一基于dos的多任务系统实现.docx》由会员分享,可在线阅读,更多相关《实验一基于dos的多任务系统实现.docx(17页珍藏版)》请在冰豆网上搜索。
![实验一基于dos的多任务系统实现.docx](https://file1.bdocx.com/fileroot1/2022-12/29/b19754b8-980b-4a09-b47f-abd08668fc29/b19754b8-980b-4a09-b47f-abd08668fc291.gif)
实验一基于dos的多任务系统实现
#include
#include
#include
#defineNTCB10/*系统允许运行的最大线程数*/
/*状态码常量定义*/
#defineFINISHED0/*表示线程处于终止态或TCB是空白状态*/
#defineRUNNING1/*表示线程牌运行态*/
#defineREADY2/*表示线程处于就绪*/
#defineBLOCKED3/*表示线程处于阻塞态*/
#defineCLOCK_NUM2/*每个线程所运行的时钟数*/
#defineNTEXT1000/*消息长度*/
#defineNBUFF5/*空闲缓冲区最大数量*/
#defineGET_INDOS0x34
#defineGET_CRIT_ERR0x5d06
charfar*indos_ptr=0;
charfar*crit_err_ptr=0;
intcurrent;/*当前进程tcb的下标*/
inttimecount;/*时钟中断次数*/
typedefstruct{
intvalue;
structTCB*wq;/*阻塞队列首个TCB*/
}semaphore;
semaphoremutex={1,NULL};
semaphoreempty={NBUFF,NULL};
semaphorefull={0,NULL};
semaphoremutexfb={1,NULL};
semaphoresfb={NBUFF,NULL};
structbuffer{
intsender;/*消息发送者的内部标识*/
intsize;/*消息长度<=NTEXT个字节*/
chartext[NTEXT];/*消息正文*/
structbuffer*next;/*指向下一个消息缓冲区的指针*/
};
structbuffer*freebuf;/*空闲缓冲区*/
semaphoremutexfb;
semaphoresfb;/*空闲缓冲区的信号量*/
semaphorefull,empty,mutex;/*用于读者写者问题*/
intpro=0;/*产品数量*/
structTCB{
unsignedchar*stack;/*线程堆栈的起始地址*/
unsignedss;/*堆栈段址*/
unsignedsp;/*堆栈指针*/
charstate;/*线程状态*/
charname[10];/*线程的外部标识符*/
structTCB*next;/*下一个TCB指针*/
/*以下三个变量用于线程通信*/
structbuffer*mq;/*接收线程的消息队列队首指针*/
semaphoremutex;/*接收线程的消息队列的互斥信号量*/
semaphoresm;/*接收线程的消息队列的计数信息量,用于实现同步*/
}tcb[NTCB];
structint_regs{
unsigned
bp/*基址指针寄存器*/
di/*目的变址寄存器*/
si/*源变址寄存器*/
ds/*数据段段地址*/
es/*附加数据段*/
dx,cx,bx,ax/*能用/累加器....*/
ip,cs,/*代码段的段地址*//*代码段的段内偏移地址*/
flags,/*flags寄存器的允许中断位*/
off,seg;/*撤销线程代码的偏移地址*//*撤销线程代码的段址*/
};
/*def*/
/*马龙龙*/
voidInitDos(void);
intDosBusy(void);
typedefint(far*codeptr)(void);
/*self*/voidInitTcb(void);/*initializethetcb*/
voidsender();
voidreceiver();
/*曹亚娟*/
/*self*/intcreate(char*name,codeptrcode,intstck);
/*self*/voiddestroy(intid);
/*self*/voidover(void);
/*沈伟臣*/
/*self*/intfind(void);/*findthenextthread*/
/*self*/voidinterruptmy_swtch(void);/*switchtoanotherthread*/
voidinterrupt(*old_int8)(void);
/*self*/voidinterruptnew_int8(void);
/*盛竹青*/
voidtcb_state(void);
intisFinished(void);/*checkwhetherallthreadisfinished*/
voidf1(void);
voidf2(void);
voidproducer(void);
voidconsumer(void);
/*赵怀瑞*/
voidblock(structTCB**p);
voidwakeup(structTCB**p);
voidp(semaphore*sem);
voidv(semaphore*sem);
/*梁宏燏*/
/*self*/voidInitBuf(void);
/*self*/structbuffer*getbuf(void);
voidinsert(structbuffer**mq,structbuffer*buff);
voidsend(char*receiver,char*a,intsize);
/*滕越*/
/*self*/structbuffer*remov(structbuffer**mq,intsender);
/*self*/intreceive(char*sender,char*b);
voidsleep();
voidInitDos(void){
unionREGSregs;
structSREGSsegregs;
regs.h.ah=GET_INDOS;
intdosx(®s,®s,&segregs),
indos_ptr=MK_FP(segregs.es,regs.x.bx);/*MK_FP()getrealaddress*/
if(_osmajor<3)
crit_err_ptr=indos_ptr+1;
elseif(_osmajor==3&&_osminor==0)
crit_err_ptr=indos_ptr-1;
else{
regs.x.ax=GET_CRIT_ERR,
intdosx(®s,®s,&segregs);
crit_err_ptr=MK_FP(segregs.ds,regs.x.si);
}
}
intDosBusy(void){
if(indos_ptr&&crit_err_ptr)
return(*indos_ptr||*crit_err_ptr);
else
return-1;
}
voidInitTcb(void)
{
inti;
for(i=0;itcb[i].stack=NULL;
tcb[i].state=FINISHED;
tcb[i].name[0]='\0';
tcb[i].next=NULL;
tcb[i].mq=NULL;
tcb[i].mutex.value=1;
tcb[i].sm.value=0;
}
}
intcreate(char*name,codeptrcode,intstck){
inti;
structint_regs*regs_pt;
for(i=0;iif(tcb[i].state==FINISHED)
break;
}
tcb[i].stack=(char*)malloc(sizeof(char)*stck);
regs_pt=(structint_regs*)(tcb[i].stack+stck)-1;
regs_pt->cs=FP_SEG(code);
regs_pt->ip=FP_OFF(code);
regs_pt->flags=0x200;
regs_pt->ds=_DS;
regs_pt->es=_DS;
regs_pt->seg=FP_SEG(over);
regs_pt->off=FP_OFF(over);
strcpy(tcb[i].name,name);
tcb[i].state=READY;
tcb[i].ss=FP_SEG(regs_pt);
tcb[i].sp=FP_OFF(regs_pt);
printf("Thethread%shasbeencreated!
\n",tcb[i].name);
returni;
}
voiddestroy(intid){
if(tcb[id].state==FINISHED)return;
disable();
free(tcb[id].stack);
tcb[id].stack=NULL;
tcb[id].state=FINISHED;
}
voidover(){/*线程结束后的处理工作*/
destroy(current);
my_swtch();
enable();
}
intfind()
{
inti;
for(i=current+1;i!
=current;i++){
if(i==NTCB)
i=0;
if(tcb[i].state==READY){
break;
}
}
returni;
}
voidinterruptmy_swtch(void){
inti;
disable();
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING)
tcb[current].state=READY;
i=find();
_SS=tcb[i].ss;
_SP=tcb[i].sp;
tcb[i].state=RUNNING;
current=i;
timecount=0;
enable();
}
voidinterruptnew_int8(void){
(*old_int8)();
timecount++;
if(timecount>=CLOCK_NUM){
if(!
DosBusy()){
my_swtch();
}
}
}
voidTCBState(void){
inti;
for(i=0;iswitch(tcb[i].state){
case0:
printf("Thestateoftcb[%d](%s)isfinished\n",i,tcb[i].name);
break;
case1:
printf("Thestateoftcb[%d](%s)isrunning\n",i,tcb[i].name);
break;
case2:
printf("Thestateoftcb[%d](%s)isready\n",i,tcb[i].name);
break;
case3:
printf("Thestateoftcb[%d](%s)isblocked\n",i,tcb[i].name);
break;
}
}
}
intisFinished(){/*判断除主线程外的其他线程是否已经完成*/
inti;
for(i=1;iif(tcb[i].state!
=FINISHED)
return0;
}
return1;
}
voidblock(structTCB**pptcb){
structTCB*tmp;
disable();
tcb[current].state=BLOCKED;
if(*pptcb==NULL)
*pptcb=&tcb[current];
else{
tmp=*pptcb;
while(tmp->next!
=NULL){
tmp=tmp->next;
}
tmp->next=&tcb[current];
}
my_swtch();
enable();
}
voidwakeup(structTCB**pptcb){
disable();
if(*pptcb==NULL)
return;
(*pptcb)->state=READY;
*pptcb=(*pptcb)->next;
enable();
}
voidp(semaphore*sem){
structTCB**qp;
disable();
sem->value=sem->value-1;
/*printf("sem->value=%d\n",sem->value);*/
if(sem->value<0){
qp=&(sem->wq);
block(qp);
}
enable();
}
voidv(semaphore*sem){
structTCB**qp;
disable();
qp=&(sem->wq);
sem->value=sem->value+1;
/*printf("sem->value=%d\n",sem->value);*/
if(sem->value<=0)
wakeup(qp);
enable();
}
voidInitBuf(void){
inti;
structbuffer*tmp;
freebuf=(structbuffer*)malloc(sizeof(structbuffer));
for(i=1,tmp=freebuf;itmp->next=(structbuffer*)malloc(sizeof(structbuffer));
tmp=tmp->next;
tmp->next=NULL;
}
}
structbuffer*getbuf(void){
structbuffer*buff;
buff=freebuf;
freebuf=freebuf->next;
return(buff);
}
voidinsert(structbuffer**mq,structbuffer*buff){
structbuffer*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;
}
}
voidsend(char*receiver,char*a,intsize){
structbuffer*buff;
inti,id=-1;
disable();
for(i=0;i/*如果接收者线程不存在,则不发送,立即返回*/
if(strcmp(receiver,tcb[i].name)==0){
id=i;
break;
}
}
if(id==-1){
printf("Error:
Receivernotexist!
\n");
enable();
return;
}
/*获取空闲消息缓冲区*/
p(&sfb);
p(&mutexfb);
buff=getbuf();
v(&mutexfb);
/*填写缓冲区各项信息*/
buff->sender=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();
}
structbuffer*remov(structbuffer**mq,intsender){
inti,j;
structbuffer*front,*rear;
front=*mq;rear=*mq;
while(front!
=NULL){
if(front->sender==sender)
break;
rear=front;
front=front->next;
}
if(front==*mq)
*mq=(*mq)->next;
else
rear->next=rear->next->next;
returnfront;
}
intreceive(char*sender,char*str){/*取出sender发出的消息并复制到str中*/
structbuffer*buff,*tmp;
inti,id=-1,size;
disable();
for(i=0;i/*printf("sender=%s,tcb[i].name=%s\n",sender,tcb[i].name);*/
if(strcmp(sender,tcb[i].name)==0){
id=i;
break;
}
}
if(id==-1){
printf("Error:
Sendernotexist!
!
\n");
enable();
return;
}
/*printf("threa2findid=%d\n",id);*/
/*当前线程消息队列是否空闲*/
p(&tcb[current].sm);
p(&tcb[current].mutex);
buff=remov(&(tcb[current].mq),id);
v(&tcb[current].mutex);
if(buff==NULL)/*返回空指针是没有sender的消息,不可能消息队列为空因为p(&tcb[current].sm)会阻塞的*/
{
v(&tcb[current].sm);
enable();
return0;
}
size=buff->size;
/*printf("getmessagesucces\n");*/
for(i=0;isize;i++)
str[i]=buff->text[i];
/*将取完消息后的消息缓冲区插入到系统空闲消息缓冲队列中freebuf*/
buff->next=NULL;
buff->sender=-1;
buff->size=0;
buff->text[0]='\0';
p(&mutexfb);
if(freebuf==NULL)
freebuf=buff;
else{
tmp=freebuf;
while(tmp->next!
=NULL){
tmp=tmp->next;
}
tmp->next=buff;
}
v(&mutexfb);
v(&sfb);
enable();
returnsize;
}
void_sleep(){
intk1,k2;
for(k1=0;k1<=10000;k1++)
for(k2=0;k2<=10000;k2++);
}
voidsender(void){
inti,k1,k2;
charsendStr[30];
printf("thread1starttosendmessage\n");
for(i=0;i<10;i++){
sprintf(sendStr,"thisis%dmessagefromthread1",i);
send("receiver",sendStr,strlen(sendStr)+1);
printf("thread1sendmessage%d\n",i);
_sleep();
}
printf("thread1sendmeesageover\n");
}
voidreceiver(void){
inti;
charrecStr[30];
for(i=0;i<10;i++){
receive("sender",recStr);
printf("%s\n",recStr);
_sleep();
_sleep();
}
}
voidproducer(void){
while
(1){
p(&empty);
p(&mutex);
pro++;
printf("producerproductaproductpro=%d\n",pro);
v(&mutex);
v(&full);
_sleep();
}
}
voidconsumer(void){
while
(1){
p(&full);
p(&mutex);
printf("consumeruseaproductpro=%d\n",pro);
pro--;
v(&mutex);
v(&empty);
_sleep();
_sleep();
}
}
voidf1(void){
inti;
for(i=0;i<40;i++