⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 duoxiancheng.c

📁 基于线程的多任务系统的实现
💻 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(&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 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 + -