操作系统-信号量机制的一些习题

1:生产者消费者问题

生产者和消费者共享一个初始值为0,大小为n的缓冲区。

当缓冲区未满时,生产者才能生产产品。

当缓冲区未空时,消费者才能消费产品。

缓冲区属于临界资源,生产者和消费者需要互斥的访问。

semaphore mutex=1    //互斥信号量,生产者和消费者互斥访问缓冲区

semaphore  empty=n   //同步信号量,表示空缓冲区的数量

semaphore  full=0         //同步信号量,表示产品数量即非空缓冲区的数量
    

producer ( ){
		while(1){
            生产产品
            p(empty)//申请空缓冲区
	        p(mutex);    //申请缓冲区的访问
		    放入空缓冲区
	        v(mutex);    //取消对缓冲区的访问
            v(full);          // 增加一个产品,即增加一个非空缓冲区
        }
}
consumer( ){
        while(1){
            p(full);   //申请非空缓冲区
            p(mutex);  //申请缓冲区的访问
            从缓冲区取出
            v(mutex);  //取消对缓冲区的访问
            v(empty);  //增加一个空缓冲区
            消费产品
        }
}

注意:对p(empty)/p(full)和p(mutex)的顺序不可以调换,如果调换会产生死锁。

  1. 如果此时缓冲区为满,如果生产者进程申请了对缓冲区的访问,而此时没有空缓冲区,生产者进程将会阻塞,而消费者进程无法进入缓冲区,消费者进程也会阻塞。
  2. 如果此时缓冲区为空,如果消费者进程申请了对缓冲区的访问,而此时没有非空缓冲区,消费者进程将会阻塞,而生产者进程无法进入缓冲区,生产者进程也会阻塞。

注意:生产者生产产品,消费者消费产品的代码不能放到缓冲区访问期间,会降低程序的并发度

2: 多生产者多消费者问题

在这里插入图片描述

semaphore   plant=0  //同步信号量,表示盘子还可以放几个水果
semaohore   apple=0  //同步信号量,表示盘子中苹果的数量
semaphore   orange=0 //同步信号量,表示盘子中橘子的数量
    
    dad( ){
    准备苹果
    p(plant);
    放入苹果
    v(apple);
    }

    mom( ){
    准备橘子
    p(plant);
    放入橘子
    v(orange);
    }
	
    daughter( ){
    p(apple);
    取走苹果
    v(plant);
    吃苹果
    }

	son( ){
    p(orange);
    取走橘子
    v(plant);
    吃橘子
    }
    

注意:此时不需要设置对盘子的互斥访问量 semaphore mutex=1,因为此时apple orange plant 三个同步信号量的值最多有一个为1。在任何时刻只能由一个进程的p操作不会被阻塞,并进去临界区。

桌上有一空盘,只允许存放一个水果。爸爸可向盘中放苹果,也可向盘中放桔子。儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘中空时一次只能放一只水果供吃者取用,请用P、V原语实现爸爸、儿子、女儿三个并发进程的同步。

semaphore  plant=1  //同步信号量,表示盘子可存放水果的数量
semaphore  apple=0  //同步信号量,表示盘子中苹果的数量
semaphore  orange=0 //同步信号量,表示盘子中橘子的数量
    
dad( ){
    准备水果
    p(plant);
    放水果
    if(苹果){
      v(apple);
    }else{
      v(orange);
    }
}


daughter( ){
    p(apple);
    拿走苹果
    v(plant);
    吃苹果
}

son( ){
    p(orange);
    拿走橘子
    v(plant);
    吃橘子
}

3:哲学家问题

在这里插入图片描述

semaphore chopstick[5]{1,1,1,1,1} //表示五只筷子 从0-4编号
semaphore mutex=1 //哲学家之间 互斥取筷子
    pi( ){
    while(1){
        p(mutex);
        p(chopstick[i]);//左边筷子
        p(chopstick[(i+1)%5])//右边筷子
        v(mutex);
        吃饭
        v(chopstick[i]);//左边筷子
        v(chopstick[(i+1)%5])//右边筷子
        思考
    }
    }
  1. 设置mutex互斥信号量,哲学家之间互斥的取筷子
  2. 最多允许四位哲学家取筷子
  3. 奇数的哲学家先拿左边筷子,再拿右边筷子,而偶数哲学家相反

4:读写者问题

在这里插入图片描述

默认读者优先:

semaphore  rw=1   //对文件的互斥访问
int count =0      //记录当前读进程的个数
semaphore  mutex=1 //保证对count变量的互斥访问

    writer( ){
    p(rw);
    写文件
    v(rw);
    }

    reader( ){
        while(1){
            p(mutex);
            if(count==0){
                p(rw);
            }
            count++;
            v(mutex);
            读文件
            p(mutex);
            count--;
            if(count==0){
                v(rw);
            }
            v(mutex);
        }
    }

读写公平:

semaphore  rw=1   //对文件的互斥访问
int count =0      //记录当前读进程的个数
semaphore  mutex=1 //保证对count变量的互斥访问
semaphore  w=1    //读写公平
writer( ){
p(w);
p(rw);
写文件
v(rw);
v(w);
}

reader( ){
    while(1){
        p(w);
        p(mutex);
        if(count==0){
            p(rw);
        }
        count++;
        v(mutex);
        v(w);
        读文件
        p(mutex);
        count--;
        if(count==0){
            v(rw);
        }
        v(mutex);
    }
}
  • 6
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值