-- 作者:lukui
-- 发布时间:11/17/2007 12:04:00 PM
--
基于TURBO C环境下实现上述部分功能的算法,下面附以程序供参考 #include <stdlib.h> #include <dos.h> #include<stdio.h> #include<math.h> #define GET_INDOS 0x34 #define GET_CRIT_ERR 0x5d06 #define BLANK -1 #define FINISHED 0 #define RUNNING 1 #define READY 2 #define BLOCKED 3 #define NTCB 10 #define TL 3 #define NBUF 10 #define NTEXT 50 char far* indos_ptr=0; char far* crit_err_ptr=0; int timecount=0; int current=-1; char b[200]; char words[200]; typedef struct { int value; struct TCB* wq; }semaphore;/*记录型信号量的结构*/ semaphore mutexfb={1,NULL};/*互斥信号量*/ semaphore sfb={10,NULL};/*空闲缓冲队列记数信号量*/ semaphore mutexre={0,NULL}; semaphore mutexse={0,NULL}; struct buffer{ int sender; int size; char text[NTEXT]; struct buffer* next; }*freebuf;/*消息缓冲区数据结构*/ struct TCB { unsigned char* stack;/*堆栈的起始地址*/ unsigned ss;/*堆栈的段址*/ unsigned sp;/*堆栈指针*/ char state;/*进程状态*/ char name[10];/*线程的外部标识符*/ int value; struct TCB* next; struct buffer *mq; semaphore mutex; semaphore sm; }tcb[NTCB]; struct int_regs { unsigned Bp,DI,SI,DS,ES,DX,CX,BX,AX,IP,CS,Flags,off,seg; };/*现场保护和恢复的数据结构*/ typedef int(far* codeptr)(void); void interrupt (*old_int8)();/*原来的时间中断程序*/ int DosBusy(void); void InitIndos(void); void InitTcb(); void interrupt new_int8(void);/*具有按时间片调度功能的新的时钟中断函数*/ void interrupt swtch();/*因其它原因引起CPU调度*/ void send(char *receiver,char *a,int size); void receive(char *sender,char *a); void p(semaphore *sem);/*信号量P操作*/ void v(semaphore *sem);/*信号量V操作*/ int Create(char* name,codeptr code,int stacklen,int value); void Destroy(int i); /*void f1() { int i,j; char msg[NTEXT]; for(i = 1; i <= 50; i ++) { inttostr(msg, i * i); send("f2", msg, NTEXT); v(&mutexre); p(&mutexse); for(j = 0; j <= 1000; j ++); } }*/ /*void f2() { int i, j; char msg[NTEXT]; for(i = 1; i <= 50; i ++) { p(&mutexre); receive("f1", msg); v(&mutexse); printf("%d * %d = %s\n", i, i, msg); for(j = 0; j <= 1000; j ++); } }*/ /* InitInDos This Funtion to get the address of INDOS and CRIT_ERR flags*/ void InitInDos() { union REGS regs; struct SREGS segregs; /*get the address of INDOS flag*/ regs.h.ah=GET_INDOS; intdosx(®s,®s,&segregs); indos_ptr=MK_FP(segregs.es,regs.x.bx); /*get the address of CRIT_ERR flag*/ if(_osmajor<3) crit_err_ptr=indos_ptr+1; else if(_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); } } /* DosBusy Function return non_zero is busy*/ int DosBusy(void) { if(indos_ptr&&crit_err_ptr) return (*indos_ptr||*crit_err_ptr); else return(-1); } void InitTcb() { int i; for(i=0;i<NTCB;i++) { tcb[i].state=BLANK; tcb[i].mq=NULL; tcb[i].mutex.value=1; tcb[i].mutex.wq=NULL; tcb[i].sm.value=0; tcb[i].sm.wq=NULL; } } void over() { Destroy(current); swtch(); } int Create(char* name,codeptr code,int stacklen,int value) { int i; char *p; struct int_regs* pt; for(i=1;i<NTCB;i++) { if(tcb[i].state==BLANK||tcb[i].state==FINISHED) break; } if(i==NTCB) return -1; tcb[i].value=value; strcpy(tcb[i].name,name); tcb[i].stack=p=(unsigned char*)malloc(stacklen); p=p+stacklen; pt=(struct int_regs *)p; pt--; pt->Flags=0x200; pt->CS=FP_SEG(code); pt->IP=FP_OFF(code); pt->off=FP_OFF(over); pt->seg=FP_SEG(over); pt->DS=_DS; pt->ES=_ES; tcb[i].sp=FP_OFF(pt); tcb[i].ss=FP_SEG(pt); tcb[i].state=READY; return i; } void Destroy(int i) { if(tcb[i].state==RUNNING) { disable(); tcb[i].state=FINISHED; free(tcb[i].stack); enable(); } return; } void tcb_state() { int i; for(i=0;i<NTCB;i++) if(tcb[i].state!=BLANK) { switch(tcb[i].state) { case FINISHED: printf("tcb[%d] is FINISHED\n",i); break; case RUNNING: printf("tcb[%d] is RUNNING\n",i); break; case READY: printf("tcb[%d] is READY\n",i); break; case BLOCKED: printf("tcb[%d] is BLOCKED\n",i); break; } } } int Find() { int i,j; for(i=0;i<NTCB;i++) if(tcb[i].state==READY&&i!=current) break; if(i==NTCB) return -1; for(j=i+1;j<NTCB;j++) { if(tcb[j].state==READY&&j!=current) if(tcb[j].value>tcb[i].value) i=j; } return i; } void Subvalue( void ) { tcb[current].value -=2; } void interrupt new_int8(void) { int i; (*old_int8) (); timecount++; if(timecount==TL) { if(!DosBusy()) { disable(); tcb[current].ss=_SS; tcb[current].sp=_SP; Subvalue(); if(tcb[current].state==RUNNING) tcb[current].state=READY; i=Find(); if(i<0) i=0 ; _SS=tcb[i].ss; _SP=tcb[i].sp; tcb[i].state=RUNNING; current=i; timecount=0; enable(); } } } void interrupt swtch() { int i; i=Find(); if(i<0) i=0 ; disable(); tcb[current].ss=_SS; tcb[current].sp=_SP; if(tcb[current].state==RUNNING) tcb[current].state=READY; _SS=tcb[i].ss; _SP=tcb[i].sp; tcb[i].state=RUNNING; current=i; enable(); } int all_finished() { int i; for(i=1;i<NTCB;i++) if(tcb[i].state==RUNNING||tcb[i].state==BLOCKED||tcb[i].state==READY) return 0; return 1; } void block(struct TCB** p) { struct TCB* p1; tcb[current].state=BLOCKED; if((*p)==NULL) *p=&tcb[current]; else { p1=*p; while(p1->next!=NULL) p1=p1->next; p1->next=&tcb[current]; } tcb[current].next=NULL; swtch(); } void wakeup_first(struct TCB**p) { struct TCB *p1; if((*p)==NULL) return ; p1=(*p); (*p)=(*p)->next; p1->state=READY; p1->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_first(qp); enable(); } struct buffer *Initbuf(void) { struct buffer *p,*pt,*pt2; int i; pt2=pt=(struct buffer*)malloc(sizeof(struct buffer));/*首节点*/ pt->sender=-1; pt->size=0; strcpy(pt->text,""); pt->next=NULL; for(i=0;i<NBUF-1;i++) { p=(struct buffer*)malloc(sizeof(struct buffer)); p->sender=-1; p->size=0; p->text[NTEXT]='\0'; p->next=NULL; pt2->next=p; pt2=p; } return pt; } struct buffer *getbuf(void) { struct buffer *buff; buff=freebuf; freebuf=freebuf->next; return(buff); } void putbuf(struct buffer* pt) { struct buffer* p=freebuf; while(p->next!=NULL) p=p->next; p->next=pt; pt->next=NULL; } 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; } } 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("Error:Receiver not exist!\n"); enable(); return ; } p(&sfb); p(&mutexfb); buff=getbuf(); v(&mutexfb); buff->sender=current; buff->size=size; buff->next=NULL; for(i=0;i<buff->size;i++,a++) buff->text[i]=*a; p(&tcb[id].mutex); insert(&(tcb[id].mq),buff); v(&tcb[id].mutex); v(&tcb[id].sm); enable(); } void receive(char *sender,char *a) { struct buffer *buff; int i; disable(); for(i=0;i<NTCB;i++) if(strcmp(sender,tcb[i].name)==0) break; if(i==NTCB) { printf("Error:Sender not exist!\n"); enable(); return ; } p(&tcb[current].sm); p(&tcb[current].mutex); buff=tcb[current].mq; tcb[current].mq=tcb[current].mq->next; for(i=0;i<buff->size;i++,a++) b[i]=buff->text[i]; b[i]='\0'; a=b; v(&tcb[current].mutex); buff->sender=-1; buff->size=0; strcpy(buff->text,""); buff->next=NULL; p(&mutexfb); putbuf(buff); v(&mutexfb); v(&sfb); enable(); } void sendfun(void) { int i,j; int size; size=strlen(words); send("receiver",words,size); for(i=0;i<10000;i++) for(j=0;j<10000;j++); /*send("receiver","what are you doing",19); for(i=0;i<1000;i++) for(j=0;j<100;j++); */ } void sendfun1( char *receiver,char *a,int size ) { int i,j; send("receiver","hello",11); for(i=0;i<10000;i++) for(j=0;j<10000;j++); send("receiver","what are you ",19); for(i=0;i<1000;i++) for(j=0;j<100;j++); } /*void sendfun1( ) { int i,j; int size; size=st send("receiver",words,size); for(i=0;i<10000;i++) for(j=0;j<10000;j++); send("receiver","what are you ",19); for(i=0;i<1000;i++) for(j=0;j<100;j++); } */ void receivefun( void ) { char *a; int i,j; receive("sender",a) ; printf("%50s\n",b); for(i=0;i<1000;i++) for(j=0;j<100;j++); /* receive("sender",a) ; printf("%s\n",b); receive("sender",a) ; printf("%s\n",b); receive("sender",a) ; printf("%s\n",b); */ } void f1() { int i,j,k,g; for(i=1;i<=50;i++) { printf("%d\n",i*i); for(j=0;j<1000;j++) for(k=0;k<1000;k++) for(g=0;g<100;g++); } } void f2()/*300以内的素数 */ { int i,j,k,g; int flag; for(i=2;i<=300;i++) { flag=0; for(j=2;j<sqrt(i*1.0)+1;j++) if(i%j==0) { if(i!=2) flag=1; break; } if(!flag) printf("%10d\n",i); for(g=0;g<10000;g++) for(k=0;k<1000;k++); } } void f3() { long f1,f2,f; int i,j,g,k; f1=1,f2=0; for(i=1;i<=30;i++) { f=f1+f2; f1=f2; f2=f; printf("%25ld\n",f); for(j=0;j<100;j++) for(k=0;k<1000;k++) for(g=0;g<1000;g++); } } void InitView() {int id; int value; disable(); printf("thread 0# is main thread\n"); printf("thread 1# is to calculate the number square from 1 to 50 \n"); printf("thread 2# is to find prime number from 1 to 100\n"); printf("thread 3# is to calculate the fib sequence number \n"); printf("thread 4# is to send message\n"); printf("thread 5# is to receive message\n"); printf("select you want to create thread Id(0<id<6):(enter id<=0 is sover)\n"); while (scanf("%d",&id)&&id>0) { getchar(); switch(id) { case 1: printf("Enter the %d# thread's value:",id); scanf("%d",&value); getchar(); Create("f1",(codeptr)f1,1024,value); printf("%d# thread is create\n",id); break; case 2: printf("Enter the %d# thread's value:",id); scanf("%d",&value); getchar(); Create("f2",(codeptr)f2,1024,value); printf("%d# thread is create\n",id); break; case 3: printf("Enter the %d# thread's value:",id); scanf("%d",&value); getchar(); Create("f3",(codeptr)f3,1024, value); printf("%d# thread is create\n",id); break; case 4: printf("Enter the %d# thread's value:",id); scanf("%d",&value); getchar(); printf("Enter your message:"); gets(words); Create("sender",(codeptr)sendfun,1024,value); printf("%d# thread is create\n",id); break; case 5: printf("Enter the %d# thread's value:",id); scanf("%d",&value); getchar(); Create("receiver",(codeptr)receivefun,1024,value); printf("%d# thread is create\n",id); break; } } enable(); } void main() { InitInDos(); InitTcb(); freebuf = Initbuf(); old_int8=getvect(8); strcpy(tcb[0].name,"main"); tcb[0].state=RUNNING; tcb[0].value=0; current=0; InitView(); Create("f1",(codeptr)f1,1024,5); Create("f2",(codeptr)f2,1024,4); Create("f3",(codeptr)f3,1024,2); gets(words); strcpy(words,"hollo\0"); Create("sender",(codeptr)sendfun,1024,6); Create("receiver",(codeptr)receivefun,1024,7); tcb_state(); setvect(8,new_int8); swtch(); while(!all_finished()); tcb[0].name[0]='\0'; tcb[0].state=FINISHED; setvect(8,old_int8); printf("\n"); tcb_state(); printf("\n Muli_task system teminated \n"); getchar(); getchar(); getchar(); gets(words); printf("\n Muli_task system teminated \n"); }
|