操作系统实验2-互斥与同步

实验分两部分,第一部分,实现互斥

     思路很简单,利用信号量,将其值初始化为1,semaphore resource = {1,NULL};
获取资源时做P()操作,释放资源使用权时做V()操作。

所以

void p1( )
{
    long i, j, k;

    p(&semlock); //获取资源使用权,如果不能获取,会被放到信号量队列中等待资源可用被唤醒
    //中间过程相当于是在使用这个资源(模拟)
    for(i=0; i<40; i++)
    {
        putchar('a');

        for(j=0; j<1000; j++)
            for(k=0; k<20000; k++);
    }
    v(&semlock); //释放资源,信号量值加1,队列中第一个线程会被唤醒(如果队列不为空)
}

void p2( )
{
    long i, j, k;
    p(&semlock);  //同p1()
    for(i=0; i<20; i++)
    {
        putchar('b');

        for(j=0; j<1000; j++)
            for(k=0; k<20000; k++);
    }
    v(&semlock);
}
另外,我们要更改Find()调度程序,找到没有被阻塞的线程来调度

int Find()
{
    int i,j;

    for(i = 1; i < NTCB; i++)
    {
        if(tcb[i].state != FINISHED && tcb[i].state != BLOCKED) return i;
    }

    return 0;
}
到这里,互斥锁就完成了。上最终代码:

#include <stdlib.h>
#include <dos.h>
#include <stdio.h>

#define GET_INDOS 0x34        /* 34H 系统功能调用    */
#define GET_CRIT_ERR 0x5d06    /* 5D06H号系统功能调用 */

#define BLANK -1
#define FINISHED 0       /*     终止    */
#define RUNNING 1        /*   执行  */
#define READY 2          /*   就绪  */
#define BLOCKED 3        /*   阻塞  */
#define NTCB 3       /* 系统线程的最大数 */

#define TL 10           /* 时间片大小  */
#define NBUF 10        /* 消息缓冲区数目 */
#define NTEXT 50             /* 文本输出大小  */

char far* intdos_ptr=0;
char far* crit_err_ptr=0;
int timecount=0;
int current=-1;

typedef unsigned int UINT16;

typedef struct/* 信号量 */
{
    int value;
    struct TCB* wq;
} semaphore;

int critical = 0; //

semaphore semlock = {1,NULL};

struct TCB            /* 线程控制块  */
{
    unsigned char* stack;          /* 堆栈的起始地址  */
    unsigned ss;
    unsigned sp;            /* 堆栈段址和堆栈指针 */
    char state;             /* 进程状态   */
    char name[10];          /* 线程的外部标识符  */
    int value;             /*优先级*/
    struct TCB* next;       /* 指向控制快指针  */
    semaphore mutex;        /* 互斥信号量   */
} 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)(void);


int DosBusy(void);
void InitIndos(void);
void InitTcb();
void interrupt new_int8(void);
void interrupt swtch();

void p(semaphore *sem);
void v(semaphore *sem);

int Create(char* name,codeptr code,int stacklen,int prio);  /* 创建线程 */
void Destroy(int i);

void p1( )
{
    long i, j, k;

    p(&semlock);
    for(i=0; i<40; i++)
    {
        putchar('a');

        for(j=0; j<1000; j++)
            for(k=0; k<20000; k++);
    }
    v(&semlock);
}

void p2( )
{
    long i, j, k;
    p(&semlock);
    for(i=0; i<20; i++)
    {
        putchar('b');

        for(j=0; j<1000; j++)
            for(k=0; k<20000; k++);
    }
    v(&semlock);
}


void InitInDos()      /* 取得INDOS标志和严重错误标志地址 */
{
    union REGS regs;
    struct SREGS segregs;

    regs.h.ah=GET_INDOS;      /* 使用34H号系统功能调用 */
    intdosx(&regs,&regs,&segregs);

    intdos_ptr=MK_FP(segregs.es,regs.x.bx);
    if(_osmajor<3)
        crit_err_ptr=intdos_ptr+1;      /* 严重错误在INDOS后一字节处 */
    else if(_osmajor==3&&_osminor==0)
        crit_err_ptr=intdos_ptr-1;      /* 严重错误在INDOS前一字节处 */
    else
    {
        regs.x.ax=GET_CRIT_ERR;
       
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值