当前位置: 代码迷 >> 综合 >> 【考研】操作系统:2009年真题45(同步互斥问题)
  详细解决方案

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

热度:100   发布时间:2023-09-22 20:37:47.0

前言

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

同类型题目:

【考研】操作系统: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 取走各自需要的数)

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

(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 发出信号elseV(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 发出信号elseV(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

  相关解决方案