操作系统课程设计--基于线程的多任务系统的实现
2010-07-08 09:45
851 查看
#include<stdio.h> #include<dos.h> #include<stdlib.h> #define GET_INDOS 0X34 #define GET_GRIT_ERR 0X5D06 #define NTCB 4 /*TCB数量*/ #define NBUF 10 #define TIMEOUT 2 /*时间片轮转时间*/ #define MSIZE 50 /*线程的五种状态,即开始,完成,运行,就绪和阻塞*/ #define START -1 #define FINISH 0 #define RUNNING 1 #define READY 2 #define BLOCK 3 int timeCount=0; int currentTcb=-1; char far *indos_ptr = 0 ; char far *crit_err_ptr = 0 ; typedef int(far* codeptr)(); /*定义一个线程私有堆栈结构体*/ struct int_regs{ unsigned BP,DI,SI,DS,ES,DX,CX,BX,AX,IP,CS,Flags,Off,Seg; }; typedef struct{ int value; struct TCB *wq; }semaphore; semaphore empty={NBUF,NULL}; semaphore mutexbuf={1,NULL}; struct buffer{ int sender; int size; char message[MSIZE]; struct buffer *next; }*freebuff,*lastbuff; struct TCB{ unsigned char *stack; unsigned ss; unsigned sp; int priority; char state; char name[10]; struct buffer *mq; semaphore mutex; semaphore sm; struct TCB *next; }tcb[NTCB]; void InitBuff(); void freeBuffer(); void InitTCB(); void InitDos(); int DosBusy(); void destroy(int i); void over(); int create_thread(char *name, codeptr code, int stacklen, int priority); void TcbState(); int seekNext(); void interrupt(*old_int8)(void); void interrupt other_swtch(void); int finish(); void block(struct TCB **qp); void wakeup(struct TCB **qp); void p(semaphore *sem); void v(semaphore *sem); void insertBuff(struct buffer **mq,struct buffer *buff); struct buffer *getBuffer(); void send(char *receiver,char *a,int size); void receiveBackBuffer(struct buffer *buff); struct buffer *get_mq(struct buffer **qp); void receive(); void f1(); void f2(); void InitBuff() { int i; struct buffer *tempBuffer1,*tempBuffer2; tempBuffer1=(struct buffer *)malloc(sizeof(struct buffer)); freebuff=tempBuffer1; for(i=0;i<NBUF;i++) { tempBuffer2=(struct buffer *)malloc(sizeof(struct buffer)); tempBuffer1->next=tempBuffer2; tempBuffer1=tempBuffer2; } tempBuffer1->next=NULL; lastbuff=tempBuffer1; } void freeBuffer() { struct buffer *temp; int i; if(freebuff!=NULL&&freebuff->next!=NULL) { free(freebuff); return ; } while(freebuff->next!=NULL) { temp=freebuff; freebuff=freebuff->next; free(temp); } } void InitTCB() { int i; for(i=0;i<NTCB;i++) { tcb[i].priority=0; tcb[i].state=START; tcb[i].name[0]='/0'; tcb[i].mq=NULL; tcb[i].mutex.value=1; tcb[i].mutex.wq=NULL; tcb[i].sm.value=0; tcb[i].sm.wq=NULL; tcb[i].next=NULL; } } void InitDos() { union REGS regs; struct SREGS segregs; regs.h.ah=GET_INDOS; intdosx(®s,®s,&segregs); indos_ptr=MK_FP(segregs.es,regs.x.bx); if(_osmajor<3) { crit_err_ptr=indos_ptr+1; } else if(_osmajor==3&&_osmajor==0) { crit_err_ptr=indos_ptr-1; } else { regs.x.ax=GET_GRIT_ERR; intdosx(®s,®s,&segregs); crit_err_ptr=MK_FP(segregs.ds,regs.x.si); } }/*初始化DOS,取得INDOS标志和严重错误标志地址*/ int DosBusy() { if(indos_ptr&&crit_err_ptr) { return(*indos_ptr||*crit_err_ptr); } else { return(-1); } }/*用于判断当前DOS是否处于繁忙状态*/ void destroy(int i) { if(tcb[i].state==RUNNING) { disable(); tcb[i].state=FINISH; free(tcb[i].stack); enable(); } } void over() { destroy(currentTcb); printf("%s has finished!/n/n", tcb[currentTcb].name); other_swtch(); } /*创建线程*/ int create_thread(char *name, codeptr code, int stacklen, int priority) { struct int_regs *stack; int freetcb; for(freetcb=1;freetcb<NTCB;freetcb++) { if(tcb[freetcb].state==START||tcb[freetcb].state==FINISH) break; } if(freetcb==NTCB) { printf("Fail create!/n"); return -1; } /*初始化TCB中各变量的值*/ tcb[freetcb].priority=priority; tcb[freetcb].state=READY; strcpy(tcb[freetcb].name,name); tcb[freetcb].stack=(unsigned char *)malloc(stacklen); tcb[freetcb].stack=tcb[freetcb].stack+stacklen; stack=(struct int_regs *)tcb[freetcb].stack-1; /*私有堆栈赋值*/ stack->DS=_DS; stack->ES=_ES; stack->Flags=0x200; stack->CS=FP_SEG(code); stack->IP=FP_OFF(code); /*over函数压入堆栈,在线程结束时,作为返回值*/ stack->Off=FP_OFF(over); stack->Seg=FP_SEG(over); /*将TCB私有堆栈的段址和栈顶指针记录到TCB中,在TCB切换时要用*/ tcb[freetcb].ss=FP_SEG(stack); tcb[freetcb].sp=FP_OFF(stack); /*printf("freetcb %d/n",tcb[freetcb].priority);*/ return freetcb; } void TcbState() { int i; for(i=0;i<NTCB;i++) { switch(tcb[i].state) { case START: printf("/n tcb[%d] %s/'s state is starting;",i,tcb[i].name); break; case FINISH: printf("/n tcb[%d] %s/'s state is finished;",i,tcb[i].name); break; case RUNNING: printf("/n tcb[%d] %s/'s state is running;",i,tcb[i].name); break; case READY: printf("/n tcb[%d] %s/'s state is ready;",i,tcb[i].name); break; case BLOCK: printf("/n tcb[%d] %s/'s state is blocked;",i,tcb[i].name); break; } } printf("/n"); } int seekNext() { int i,n_tcb=0,pri=0; disable(); for(i=1;i<NTCB;i++) { /*实现寻找一个优先级最高并在READY状态下的TCB*/ if(tcb[i].state==READY&&tcb[i].priority>pri) { n_tcb=i; pri=tcb[i].priority; } } /*实现TCB的优先级的变化*/ for( i=1;i<NTCB&&tcb[i].state==READY;i++) { if(i!=n_tcb) { tcb[i].priority++; } } enable(); return n_tcb; } /*线程调度函数*/ void interrupt new_int8() { disable(); (*old_int8)(); timeCount++; if(timeCount>=TIMEOUT) { if(!DosBusy()) { /*printf("%s 's time is up/n",tcb[currentTcb].name);*/ tcb[currentTcb].ss=_SS; tcb[currentTcb].sp=_SP; if(tcb[currentTcb].state==RUNNING) { tcb[currentTcb].state=READY; } currentTcb=seekNext(); _SS=tcb[currentTcb].ss; _SP=tcb[currentTcb].sp; tcb[currentTcb].state=RUNNING; timeCount=0; } } enable(); }/*时间中断*/ void interrupt other_swtch(void) { disable(); if(tcb[currentTcb].state==FINISH) { currentTcb=seekNext(); tcb[currentTcb].state=RUNNING; _SS=tcb[currentTcb].ss; _SP=tcb[currentTcb].sp; } else { tcb[currentTcb].ss=_SS; tcb[currentTcb].sp=_SP; if(tcb[currentTcb].state==RUNNING) { tcb[currentTcb].state=READY; } currentTcb=seekNext(); _SS=tcb[currentTcb].ss; _SP=tcb[currentTcb].sp; tcb[currentTcb].state=RUNNING; } enable(); } int finish() { int i; disable(); for(i=1;i<NTCB;i++) { if(tcb[i].state==RUNNING||tcb[i].state==READY||tcb[i].state==BLOCK) { enable(); return 0; } } enable(); return 1; } /*qb为阻塞队列,找到阻塞队列中最后的插入位置,并将tcb加入*/ void block(struct TCB **qp) { struct TCB *temp; disable(); tcb[currentTcb].state=BLOCK; if((*qp)==NULL) { (*qp)=&tcb[currentTcb]; } else { temp=*qp; while(temp->next!=NULL) { temp=temp->next; } temp->next=&tcb[currentTcb]; } tcb[currentTcb].next=NULL; other_swtch(); enable(); } /*qp为阻塞队列,截取队列的第一个放在就绪队列的末尾*/ void wakeup(struct TCB **qp) { struct TCB *blockHead; blockHead=(*qp); { if(blockHead!=NULL) { (*qp)=(*qp)->next; blockHead->state=READY; blockHead->next=NULL; } } } 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(); } /*放到私有TCB缓冲队列末尾*/ void insertBuff(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; } } /*freebuff指向队列的第一个*/ struct buffer *getBuffer() { struct buffer *bufList; bufList=freebuff; freebuff=freebuff->next; return (bufList); } void send(char *receiver,char *a,int size) { struct buffer *buff; int i, id=-1; disable(); for(i=0;i<NTCB;i++) { if(strcmp(receiver,tcb[i].name)==0) { id=i; break; } } if(id==-1) { printf("Can't find the receiver/n"); enable(); return; } p(&empty); p(&mutexbuf); buff=getBuffer(); v(&mutexbuf); buff->sender=currentTcb; buff->size=size; buff->next=NULL; for(i=0;i<buff->size;i++) { buff->message[i]=*(a+i); } /*实现对TCB中的消息队列互斥操作*/ p(&tcb[id].mutex); insertBuff(&tcb[id].mq,buff); v(&tcb[id].mutex); v(&tcb[id].sm); enable(); } /*接受完后把buffer还给空闲缓冲*/ void receiveBackBuffer(struct buffer *buff) { lastbuff->next=buff; lastbuff=lastbuff->next; } struct buffer *get_mq(struct buffer **qp) { struct buffer *temp; temp=(*qp); (*qp)=(*qp)->next; temp->next=NULL; return (temp); } void receive() { struct buffer *buff=NULL; disable(); if(tcb[currentTcb].mq==NULL) { printf("now there is no message in message queue,then blocked %s/n!", tcb[currentTcb].name); enable(); p(&tcb[currentTcb].sm); return ; } enable(); p(&tcb[currentTcb].sm); p(&tcb[currentTcb].mutex); buff=get_mq(&(tcb[currentTcb].mq)); v(&tcb[currentTcb].mutex); printf("%s receive a message from %s: ", tcb[currentTcb].name, tcb[buff->sender].name ); printf("%s/n/n", buff->message); p(&mutexbuf); receiveBackBuffer(buff); v(&mutexbuf); v(&empty); } void f1() { int i,j,k; char a[MSIZE]="Hello f2!"; for(i=0;i<10;i++) { putchar('a'); for(j=0;j<10000;j++) { for(k=0;k<10000;k++); } } printf("/n"); for(i=0;i<3;i++) { printf("f1 is sending message to f2!/n"); send("f2",a,MSIZE); receive(); for(j=1;j<10000;j++) { for(k=0;k<10000;k++); } } } void f2() { int i,j,k; char a[MSIZE]="Hello f1!"; for(i=0;i<10;i++) { putchar('b'); for(j=0;j<10000;j++) { for(k=0;k<10000;k++); } } printf("/n"); for(i=0;i<3;i++) { printf("f2 is sending message to f1!/n"); send("f1",a,MSIZE); receive(); for(j=0;j<10000;j++) { for(k=0;k<10000;k++); } } } int main() { disable(); InitDos(); InitTCB(); InitBuff(); old_int8=getvect(8); strcpy(tcb[0].name,"main"); tcb[0].state=RUNNING; currentTcb=0; create_thread("f1",(codeptr)f1,1024,3); create_thread("f2",(codeptr)f2,1024,1); TcbState(); setvect(8,new_int8); other_swtch(); enable(); while(!finish()) { } tcb[0].name[0]='/0'; tcb[0].state=FINISH; setvect(8,old_int8); printf("all thread have finished!/n"); TcbState(); freeBuffer(); getch(); }
相关文章推荐
- 操作系统课程设计 基于DOS的多任务系统的实现
- 杭州电子科技大学操作系统课程设计:简单文件系统的实现
- 游戏任务成就体系的实现(附三):成就系统基于Mysql+Cache的数据库访问设计实现
- 操作系统课程设计报告--虚拟文件系统的实现后附源代码
- 游戏任务成就体系的实现(附七):成就系统基于Redis的数据库访问设计实现
- 文件系统的设计与实现(操作系统课程设计)
- 用c实现“基于线程的多任务系统的实现”
- 操作系统课程设计(二)简单文件系统实现
- 操作系统课程设计--简单文件系统的实现
- [课程设计]Scrum 3.1 多鱼点餐系统开发进度(第三阶段项目构思与任务规划)
- unix文件系统模拟-操作系统课程设计
- 基于WPF系统框架设计(5)-Ribbon整合Avalondock 2.0实现多文档界面设计(二)
- 基于Winodws CE的嵌入式网络监控系统的设计与实现
- 基于三层结构的CRM系统的设计和实现
- 基于RFID的简易图书管理系统设计与实现
- 从架构设计到系统实施——基于.NET 3.0的全新企业应用系列课程(视频课程讲师:徐晓卓)
- 【VB+数控原理与系统】数控原理与系统课程设计刀具半径补偿直线-直线VB模拟软件实现
- 基于web技术的工作流管理系统设计与实现
- 基于ZooKeeper,Spring设计实现的参数系统
- 基于SOA的设备智能维护系统架构设计及实现