• 操作系统课程设计 线程的同步与互斥


    线程同步代码,里面包含互斥信号量,这里将它注释了。

    // 2.线程的同步与互斥     2015.12.11
    
    #include <dos.h>
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    int current;
    long timecount;
    #define NTCB 3
    
    #define FINISHED     0
    #define RUNNING     1
    #define READY       2
    #define BLOCKED     3
    
    #define GET_INDOS 0x34
    #define GET_CRIT_ERR 0x5d06
    
    #define TIMEINT 0x08
    
    #define TIMESLIP 20    //时间片改大
    
    #define STACKLEN 1024
    
    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  int ss;
        unsigned  int sp;
        int state;
        char name[10];
        int priority;        // 增加优先级
        semaphore sm;        // 增加记录型信号量,用于同步
        semaphore mutex;    // 增加互斥信号量
        struct TCB *next;      // 指向下一个线程的指针 
    
    }tcb[NTCB];
    
    semaphore mutex;    
    semaphore bufferSem1, bufferSem2;        
    
    void InitInDos(void);
    int DosBusy(void);
    
    void block(struct TCB **qp);
    void wakeup_first(struct TCB **qp);
    void p(semaphore *sem);
    void v(semaphore *sem);
    void p1();
    void p2();
    int Find();
    void interrupt new_swtch();
    void interrupt swtch(); 
    void interrupt (*old_int8)(void);
    void interrupt new_int8(void);
    void interrupt test_int8(void);
    void over();
    void InitTcb();
    void show_tcb_state();
    int all_finished();
    void releaseTcb();
    
    typedef void (far *funcptr)(void);
    int create(char *name, funcptr func, int stlen);
    
    void InitInDos(void)
    {
     union REGS regs;
     struct SREGS segregs;
    
     regs.h.ah=GET_INDOS;
     intdosx(&regs, &regs, &segregs);
     indos_ptr=MK_FP(segregs.es, regs.x.bx);
    
    
     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);
     }
    }
    
    int DosBusy(void)
    {
     if(indos_ptr&&crit_err_ptr)
       return(*indos_ptr||*crit_err_ptr);
     else
       return -1;
    }
    
    
    // 同步和互斥相关函数===========================================
    // 将线程插入到阻塞队列
    void block(struct TCB **qp)
    {
        struct TCB *tcbp;
        tcb[current].state = BLOCKED;
        if((*qp) == NULL)
        {
            (*qp) = &tcb[current];
        }    
        // 插入到队尾
        else
        {
            tcbp = (*qp);
            while(tcbp->next != NULL)
                tcbp = tcbp->next;
    
            tcbp->next = &tcb[current];
        }
    
        tcb[current].next = NULL;
    
        // 主动切换
        swtch();
    }
    
    // 从阻塞队列中唤醒第一个线程
    void wakeup_first(struct TCB **qp)
    {    
        struct TCB *tcbp;
        if((*qp) == NULL)
            return;
        tcbp = (*qp);
        (*qp) = (*qp)->next;
    
        tcbp->state = READY;
        tcbp->next = NULL;    
    
        //swtch();
    }
    
    // p 操作
    void p(semaphore *sem)
    {
        struct TCB **qp;
        disable();
        sem->value=sem->value-1;
        if(sem->value < 0)
        {
            qp = &(sem->wq);
            // 将线程插入到阻塞队列 
            block(qp);
        }
        enable();
    }
    
    // v 操作
    void v(semaphore *sem)
    {
        struct TCB **qp;
        disable();
        qp = &(sem->wq);
        sem->value++;
        if(sem->value <= 0)
        {
            // 从阻塞队列中唤醒第一个线程
            wakeup_first(qp);
        }
    
        swtch();
        enable();
    }
    
    // 生产者消费者问题
    void p1()
    {
    
        long i, j, k;
        
        for(i=0; i<55; i++)
        {
            p(&bufferSem1);
        
            //p(&mutex);
            putchar('a');
            //v(&mutex);
    
            v(&bufferSem2);
    
            for(j=0; j<1000; j++)
                for(k=0; k<20000; k++);
        }
        
    }
    
    void p2()
    {
        long i, j, k;
        
        for(i=0; i<50; i++)
        {
            p(&bufferSem2);
    
            //p(&mutex);
            putchar('b');
            //v(&mutex);
    
            v(&bufferSem1);
    
            for(j=0; j<1000; j++)
                for(k=0;k<20000; k++);
        }
    }
    
    int Find()
    {
        int i,j;
        i=current;
    
        while(tcb[i=((i+1)%NTCB)].state!=READY||i==current);
    
        return i;
    }
    
    void interrupt swtch()        // 其他原因CPU调度
    {
        int id; 
    
        id = Find(); 
    
        if(id ==0) 
        {
            if(tcb[1].state==FINISHED && tcb[2].state==FINISHED)
                id=0; 
            else
                id=1;
        }
    
        disable();  
        // 保存现场
        tcb[current].ss = _SS; 
        tcb[current].sp = _SP; 
    
        if(tcb[current].state == RUNNING) 
            tcb[current].state = READY; 
    
        // 切换堆栈 
        _SS = tcb[id].ss; 
        _SP = tcb[id].sp; 
    
        tcb[id].state = RUNNING; 
        current = id; 
    
        timecount = 0; 
        enable(); 
    }
    
    void interrupt new_int8(void)
    {
        int i;
    
        (*old_int8)();
        timecount++;
    
        if(timecount!=TIMESLIP)
            return;
        else
        {
            if(DosBusy())
                return;
            else
            {
                disable();
    //            asm CLI
    
                tcb[current].ss=_SS;
                tcb[current].sp=_SP;
    
                if(tcb[current].state==RUNNING)
                    tcb[current].state=READY;
    
                i=Find();
    
                if(i==current)
                    return;
    
                
                _SS=tcb[i].ss;
                _SP=tcb[i].sp;
                tcb[i].state=RUNNING;
    
                timecount=0;
                current=i;
    
                enable();
    //            asm STI
            }
        }
    }
    
    void over()
    {
        if(tcb[current].state==RUNNING)
        {
            disable();
            tcb[current].state=FINISHED;
            strcpy(tcb[current].name,NULL);
            free(tcb[current].stack);
            enable();
        }
    
        swtch();
    }
    
    void InitTcb()
    {
        unsigned int *tmp=0;
    
        //for thread 1
        //================================================
        tcb[1].state=READY;
    //    strcpy(tcb[1].name, "p1");
    
        tcb[1].stack=(unsigned char *)malloc(STACKLEN);
        memset(tcb[1].stack, 0xff, STACKLEN);
    
        tmp=(unsigned int *)(tcb[1].stack+STACKLEN-2);
        
        *tmp=FP_SEG(over);
        *(tmp-1)=FP_OFF(over);
        *(tmp-2)=0x200;    
        *(tmp-3)=FP_SEG(p1);
        *(tmp-4)=FP_OFF(p1);
        
        *(tmp-9)=_ES;
        *(tmp-10)=_DS;
        tcb[1].ss=FP_SEG(tmp-13);
        tcb[1].sp=FP_OFF(tmp-13);
    
        tcb[1].priority=2;        // 初始化优先级
        tcb[1].sm.value = 0;    // 初始化同步信号量
        tcb[1].sm.wq = NULL;
        tcb[1].mutex.value = 1;    // 初始化互斥信号量
        tcb[1].mutex.wq = NULL;
    
        //for thread 2
        //================================================
        tcb[2].state=READY;
    //    strcpy(tcb[2].name, "p2");
    
        tcb[2].stack=(unsigned char *)malloc(STACKLEN);
        memset(tcb[2].stack, 0xff, STACKLEN);
        
        tmp=(unsigned int *)(tcb[2].stack+STACKLEN-2);
    
        *tmp=FP_SEG(over);
        *(tmp-1)=FP_OFF(over);
        *(tmp-2)=0x0200;    
        *(tmp-3)=FP_SEG(p2);
        *(tmp-4)=FP_OFF(p2);
        
        *(tmp-9)=_ES;
        *(tmp-10)=_DS;
        tcb[2].ss=FP_SEG(tmp-13);
        tcb[2].sp=FP_OFF(tmp-13);
    
        tcb[2].priority=1;        // 初始化优先级
        tcb[2].sm.value = 0;    // 初始化同步信号量
        tcb[2].sm.wq = NULL;
        tcb[2].mutex.value = 1;    // 初始化互斥信号量
        tcb[2].mutex.wq = NULL;
    }
    
    void show_tcb_state()
    {
        int i;
    
        for(i=0; i<NTCB; i++)
        {
            switch(tcb[i].state)
            {
            case FINISHED:
                    printf("
    the thread %d is finished!
    ", i);
                    break;
            case RUNNING:
                    printf("the thread %d is running!
    ", i);
                    break;
            case READY:
                    printf("the thread %d is ready!
    ", i);
                    break;
            case BLOCKED:
                    printf("the thread %d is blocked!
    ", i);
                    break;
            default:
                    printf("unknown state of thread %!
    ", i);
            }
        }
    }
    
    int all_finished()
    {
        if(tcb[1].state!=FINISHED||tcb[2].state!=FINISHED)
            return -1;
        else 
            return 0;
    }
    
    void releaseTcb()
    {
        int i=0;
    
        for(i=1; i<NTCB; i++)
        {
            if(tcb[i].stack)
                free(tcb[i].stack);
        }
    }
    
    void main()
    {
        timecount=0;
    
        mutex.value = 1;
        mutex.wq = NULL;
    
        bufferSem1.value = 1;
        bufferSem1.wq = NULL;
    
        bufferSem2.value = 0;
        bufferSem2.wq = NULL;
    
        InitInDos();
        InitTcb();
    
        old_int8=getvect(TIMEINT);
    
        strcpy(tcb[0].name, "main");
        tcb[0].state=RUNNING;
        tcb[0].priority=3;
        current=0;
    
        show_tcb_state();
    
        disable();
        setvect(TIMEINT, new_int8);
        enable();
    
        while(all_finished())
        {
        //    printf("system running!
    ");    
        }
    
        tcb[0].name[0]='';
        tcb[0].state=FINISHED;
        setvect(TIMEINT, old_int8);
    
        show_tcb_state();
    
        printf("Multi_task system terminated.
    ");
    
        //system("pause");
    }
  • 相关阅读:
    转:阅读代码
    转:三个教程
    转:C/C++程序员简历模板
    转:对于一个字节(8bit)的变量,求其二进制表示中“1”的个数
    内存偏移
    转:用C++实现的一种插件体系结构-----概述
    转:用异或实现两个数的交换的问题
    转:二级指针
    转:《链接、装载与库》里的一个错误:关于调用栈
    转:你应当如何学习C++(以及编程)(rev#1)
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/5115793.html
Copyright © 2020-2023  润新知