DOS多任务系统实现

该博客展示了多任务系统的代码实现,包含线程创建、调度、信号量操作等功能。定义了任务控制块、消息缓冲区等数据结构,实现了按时间片调度的时钟中断函数,还提供了发送和接收消息的函数,可创建不同功能的线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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(&regs,&regs,&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(&regs,&regs,&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++);
   

}

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

}
void f1()/*50以内个数的平方*/
{
    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();
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");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值