您的位置:首页 > 其它

操作系统课程设计--基于线程的多任务系统的实现

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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: