【考研】操作系统:2009年真题45(同步互斥问题)

本文详细介绍了如何解决操作系统中三个进程的同步互斥问题,涉及生产者P1生成奇偶数,消费者P2、P3分别取奇偶数的场景。通过设置互斥信号量mutex、同步信号量odd和even以及empty,实现了进程间的协调。文中给出了伪代码实现,展示了同步关系图,并将问题归类为吸烟者问题。
摘要由CSDN通过智能技术生成

前言

解决同步互斥问题的思路,源于对王道讲解的总结笔记。

同类型题目:

【考研】操作系统:2019年真题43(同步互斥问题)_住在阳光的心里的博客-CSDN博客

【考研】操作系统:2015年真题45(同步互斥问题)_住在阳光的心里的博客-CSDN博客

【考研】操作系统:2014年真题47(同步互斥问题)_住在阳光的心里的博客-CSDN博客

一、思路

解决同步互斥问题,思路步骤:

1. 分析各进程之间的同步互斥关系;

2. 设置互斥信号量 mutex = 1、同步信号量(一般设可使用的资源数为empty = N)。

3. 最好画出同步互斥关系图,并判断属于哪一种类型,如生产者-消费者问题、读者-写者问题、哲学家进餐问题、吸烟者问题。

针对生产者-消费者问题、读者-写者问题、哲学家进餐问题、吸烟者问题,这些经典同步问题可以参考:

计算机操作系统——经典同步问题_御承扬的博客-CSDN博客

二、题目

45. (7分)三个进程P1、P2、P3互斥使用一个包含N(N > 0)个单元的缓冲区。
P1 每次用 produce()生成一个正整数并用 put()送入缓冲区某一空单元中;
P2 每次用 getodd()从该缓冲区中取出一个奇数并用 countodd()统计奇数个数;
P3 每次用 geteven()从该缓冲区中取出一个偶数并用 counteven()统计偶数个数。
请用信号量机制实现这三个进程的同步与互斥活动,并说明所定义的信号量的含义。要求用伪代码描述。

解:

(1)互斥资源:

P1、P2与P3互斥使用缓冲区,所以设置互斥信号量 mutex

(2)同步问题:

P1、P2 因为奇数的放置与取用而同步,设同步信号量 odd;

P1、P3 因为偶数的放置与取用而同步,设同步信号量 even;

P1、P2、P3 因为共享缓冲区,设同步信号量 empty,初值为 N。

(3)三个进程P1、P2、P3同步互斥关系图如下:

(属于吸烟者问题:一个生产者生产多种商品,多个消费者取走各自产品。即 P1 生产奇数和偶数,P2 和 P3 取走各自需要的数)

(4)伪代码如下:

semaphore mutex = 1;  // 设置互斥信号量,互斥访问缓冲区
semaphore odd = 0;    // 有几个奇数
semaphore even = 0;    // 有几个偶数
semaphore empty = N;    // 空缓冲区的数量
P1(){  // 生产者
	while(1){
        x = produce();  // 生成一个数
		P(empty);  //消耗空缓冲区的数量
		

		P(mutex);  //缓冲区是否被占用
		put();
		V(mutex);  //释放缓冲区

		if(x % 2 == 0)  // 此处判断奇偶数是重点
			V(even);  // 产偶数,向 P3 发出信号
		else
			V(odd);  // 产奇数,向 P2 发出信号
	}
	
}
P2(){  // 取奇数
	while(1){  // 也可用while(true)
		P(odd);  // 收到 P1 发来的信号,,已产生一个奇数,则 P2 消耗一个奇数

		P(mutex);  // 缓冲区是否被占用
		getodd();
        V(mutex);  // 释放缓冲区

		V(empty);   // 向 P1 发信号,多出一个空单元
		countodd(); 
	}
}
P3(){  // 取偶数
	while(1){
		P(even);  // 收到 P1 发的信号,已产生一个偶数,则 P3 消耗一个偶数

		P(mutex);  // 缓冲区是否被占用
		geteven();
		V(mutex);  // 释放缓冲区

		V(empty);  // 向 P1 发信号,多出一个空单元
        counteven();
	}
}

完整答案写法:

semaphore mutex = 1;  // 设置互斥信号量,互斥访问缓冲区
semaphore odd = 0;    // 有几个奇数
semaphore even = 0;    // 有几个偶数
semaphore empty = N;    // 空缓冲区的数量

main()
cobegin{
    Process P1()  
	while(1){  
        x = produce();  // 生成一个数
		P(empty);  //消耗空缓冲区的数量
		

		P(mutex);  //缓冲区是否被占用
		put();
		V(mutex);  //释放缓冲区

		if(x % 2 == 0)  
			V(even);  // 产偶数,向 P3 发出信号
		else
			V(odd);  // 产奇数,向 P2 发出信号
	}
	

    Process P2()  // 取奇数
	while(1){
		P(odd);  // 收到 P1 发来的信号,,已产生一个奇数,则 P2 消耗一个奇数

		P(mutex);  // 缓冲区是否被占用
		getodd();
        V(mutex);  // 释放缓冲区

		V(empty);   // 向 P1 发信号,多出一个空单元
		countodd(); 
	}


    Process P3()  // 取偶数
	while(1){
		P(even);  // 收到 P1 发的信号,已产生一个偶数,则 P3 消耗一个偶数

		P(mutex);  // 缓冲区是否被占用
		geteven();
		V(mutex);  // 释放缓冲区

		V(empty);  // 向 P1 发信号,多出一个空单元
        counteven();
	}

}coend

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

住在阳光的心里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值