📄 duoxiancheng.c
字号:
# include "stdio.h"
# include "malloc.h"
# include "stdlib.h"
# include "dos.h"
# include "time.h"
# define GET_INDOS 0x34
# define GET_CRIT_ERR 0x5d06
# define INT_MIN -32768
# define START -1
# define FINISHED 0
# define RUNNING 1
# define READY 2
# define BLOCKED 3
# define NTCB 10
# define NTEXT 100
int timecount = 0; /*时间片的初始值*/
int TLE = 2; /*时间片的最大值*/
int current=-1; /*目前的线程标识*/
char far *indos_ptr = 0;
char far *crit_err_ptr = 0;
/*记录型信号量的数据结构*/
typedef struct
{
int value;
struct TCB *wq;
}semaphore;
struct TCB
{
unsigned char *stack;/*堆栈的起始地址*/
unsigned ss;/*堆栈段址*/
unsigned sp;/*堆栈指针*/
char state ;/*进程状态*/
char name[10];/*线程的外部表示符*/
int value;
struct buffer *mq;
semaphore mutex;
semaphore sm;
struct TCB* next;
}tcb [NTCB];
struct buffer
{
int sender ;/* 消息发送者的标识数*/
int size; /*消息长度<= NEXT个字节*/
char text[NTEXT];/*消息正文*/
struct buffer *next; /*指向下个消息缓冲区的指针*/
};
/*定义一个空闲指针*/
struct buffer *freebuf;
/*现场保护和恢复的堆栈*/
struct int_regs
{
unsigned BP;
unsigned DI;
unsigned SI;
unsigned DS;
unsigned ES;
unsigned DX;
unsigned CX;
unsigned BX;
unsigned AX;
unsigned IP;
unsigned CS;
unsigned Flags;
unsigned off;
unsigned seg;
};
/*定义一个互斥信号量*/
semaphore mutexfb ={1,NULL};
/*定义一个同步信号量*/
semaphore sfb = {NTCB,NULL};
void over();
typedef int (far * codeptr)(void);
int create (char *name,codeptr code,int stacklen,int value);
void interrupt (*old_int8)(void);
void interrupt swtch(void);
int DosBusy(void);
void InitInDos(void);
void tcb_state(void);
void send(char * receicer,char *a,int size);
void receive(char *sender,char *a);
void return_buff(struct buffer *buffer);
void p(semaphore *sem);
void v(semaphore *sem);
void f1(void);
void f1(void);
void f3(void);
void f4(void);
int find();
void InitTcb();
int all_finished();
void return_buff(struct buffer *buffer);
void block(struct TCB **qp);
void wakeup_first(struct TCB **qp);
/*InitInDos
*Function to get the address of INDOS and CRIT_ERR flags
*/
void InitInDos(void)
{
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 if DOS is busy
*/
int DosBusy(void)
{
if(indos_ptr && crit_err_ptr)
return (*indos_ptr || *crit_err_ptr);
else
return (-1);/*InitDos()hasn't been called*/
}
void f1(void)
{
long i,j,k;
for(i = 0;i < 10;i++)
{
printf("a");
for(j = 0;j < 5000;j++) /*用于延时操作*/
for(k = 0;k < 5000; k++) ;
}
printf("\n");
}
void f2(void)
{
long i,j,k;
for(i=0; i<15; i++)
{
printf("b");
for(j = 0;j <6000;j++) /*用于延时操作*/
for(k = 0;k < 6000;k++) ;
}
printf("\n");
}
void f3(void)
{
int j,k;
int size = 11;
char *a = "xiaobenniao";
char *receiver = "receiver";
send(receiver,a, size);
for(j=0; j<7000; j++) /*用于延时操作*/
for(k=0; k<7000; k++)
{} ;
}
void f4(void)
{
int j,k;
char a[88];
receive("sender",a);
printf("%s",a);
for(j=0; j<8000; j++) /*用于延时操作*/
for(k=0; k<8000; k++)
{} ;
}
/*typedef int (far * codeptr)(void); */
int create (char *name,codeptr code,int stacklen,int value)
{
int i;
struct int_regs * tmp;
for(i=1; i<NTCB ; i++)
{
if(tcb[i].state == START || tcb[i].state == FINISHED)
break;
else if (tcb[i].state == READY ||tcb[i].state == BLOCKED)
continue;
else printf("no available\n");
}
strcpy (tcb[i].name,name);
tcb[i].stack = (unsigned char*)malloc(stacklen);
/*tcb[num].stack += stacklen;*/
tcb[i].value = value;
tmp=(struct int_regs *)(tcb[i].stack+stacklen)-1;
tmp->DS=_DS;
tmp->ES=_ES;
tmp->Flags=0x200;
tmp->CS=FP_SEG(code);
tmp->IP=FP_OFF(code);
tmp->off=FP_OFF(over);
tmp->seg=FP_SEG(over);
tcb[i].ss=FP_SEG(tmp);
tcb[i].sp=FP_OFF(tmp);
tcb[i].state=READY;
tcb[i].value= value;
return;
};
void over()
{
if(tcb[current].state==RUNNING)
{
disable();
tcb[current].state=FINISHED;
free(tcb[current].stack);
enable();
}
swtch();
}
int find()
{ int i,j = 0;
int v = INT_MIN;
for(i = 1;i < NTCB;i++)
{
if(i == current ) continue ;
if(tcb[i].state == READY )
{
if(v < tcb[i].value)
{
v = tcb[i].value;
j = i;
}
}
}
for(i=1; i<j; i++)
tcb[i].value = tcb[i].value+5;
for(i=j+1; i<NTCB; i++)
tcb[i].value = tcb[i].value+5;
tcb[j].value = tcb[j].value-5;
return j;
/* if(current == 0) return 2;
if(current == 1) return 2;
if(current == 2) return 1;
return 0;
*/
}
/*中断函数*/
void interrupt swtch(void)
{
disable();
/*保存现行堆栈的段址和栈顶供下次切换时用*/
tcb[current].ss=_SS;
tcb[current].sp=_SP;
if(tcb[current].state==RUNNING) tcb[current].state=READY;
/*切换堆栈*/
current=find();
/* printf("%d",current); */
_SS=tcb[current].ss;
_SP=tcb[current].sp;
tcb[current].state=RUNNING;
enable();
};
/*时间片的调度*/
void interrupt new_int8(void)
{
(*old_int8)();
timecount++;
if(timecount >= TLE)
{
if(!DosBusy())
{
disable();
tcb[current].ss = _SS;
tcb[current].sp = _SP;
if(tcb[current].state == RUNNING) tcb[current].state = READY;
current = find();
/*printf("%d",current); */
_SS = tcb[current].ss;
_SP = tcb[current].sp;
tcb[current].state = RUNNING;
timecount = 0;
enable();
}
}
return;
}
/*初始化TCB*/
void InitTcb()
{int i;
for(i =0;i < NTCB ;i++ )
{
tcb[i].state = START;
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的状态函数*/
void tcb_state(void)
{int i;
for(i = 1;i <= (NTCB-1);i++)
{
if(tcb[i].state == START ) printf("The %dst thread hasnot been created!\n",i);
else if (tcb[i].state == READY) printf("The %dst thread has been created!\n",i);
else if (tcb[i].state == BLOCKED) printf("The %dst thread has been blocked!\n",i);
else if (tcb[i].state == FINISHED) printf("The %dst thread has been finished!\n",i);
}
}
/*检查所有的线程是否都已经结束*/
int all_finished()
{
int i;
for(i = 1;i < NTCB; i++)
{
if(tcb[i].state != FINISHED&&tcb[i].state != START )
return 0;
}
return 1;
}
/*从空闲消息缓冲对列列头*/
struct buffer *getbuf(void)
{
struct buffer *buff;
buff = freebuf;
freebuf = freebuf->next;
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;
}
}
void send(char * receiver,char *a,int size)
{
struct buffer *buff;
int i,id = -1;
disable();
for(i=1; 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, *q;
int i,id = -1;
p(&tcb[current].sm);
disable();
for(i=0; i<NTCB; i++)
if(strcmp(sender,tcb[i].name) == 0)
{
id = i;
break;
}
if(id == -1)
{
printf("\nThe %s is not exist!",sender);
enable();
return;
}
p(&tcb[current].mutex);
for(buff=tcb[current].mq; buff!=NULL; q=buff,buff=buff->next)
if(buff->sender == id)
break;
for(i=0; i<buff->size; i++,a++)
*a = buff->text[i];
*a='\0';
q->next = buff->next;
v(&tcb[current].mutex);
p(&mutexfb);
return_buff(buff);/*还没有写这个函数*/
v(&mutexfb);
v(&sfb);
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_first(qp);
enable();
}
/*申请空的缓冲区*/
void apply_for()
{
int i;
struct buffer *temp,*p;
freebuf = (struct buffer *)malloc(sizeof(struct buffer ));
temp = freebuf;
for(i=1; i<NTCB; i++)
{
p = (struct buffer *)malloc(sizeof(struct buffer ));
temp->next = p;
temp = p;
}
}
void return_buff(struct buffer *buffer)
{
buffer->next = freebuf->next;
freebuf->next = buffer;
}
void block(struct TCB **p)
{
struct TCB *q = *p;
tcb[current].state = BLOCKED;
if(*p==NULL)
*p=&tcb[current];
else
{
while(q->next)
q=q->next;
q->next=&tcb[current];
}
tcb[current].next=NULL;
swtch();
}
void wakeup_first(struct TCB **p)
{
if(*p==NULL)return;
(*p)->state=READY;
*p=(*p)->next;
}
void main()
{
InitInDos();
InitTcb();
apply_for();
old_int8 = getvect(8);
/*创建0#线程*/
strcpy(tcb[0].name,"main");
tcb[0].state = RUNNING;
current = 0;
create("f1",(codeptr)f1,1024,5);
create("f2",(codeptr)f2,1024,10);
create("sender",(codeptr)f3,1024,15);
create("receiver",(codeptr)f4,1024,20);
tcb_state();
/*启动多个线程的并发运行*/
setvect(8,new_int8);
swtch();
while(!all_finished());
tcb[0].name[0] = '\0';
tcb[0].state = FINISHED;
setvect(8,old_int8);
tcb_state();
printf("\n Multi_task system terminated.\n") ;
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -