【一个生产者一个消费者问题】

有一计算进程和打印进程,它们共享一个单缓冲区,计算进程不断地计算出一个整形结果并将它放入单缓冲区中,打印进程则负责从单缓冲区中取出每一个结果打印,用信号量实现。

【操作系统】进程:生成者-消费者问题_java

 

设置信号量full表示资源个数,empty表示资源类型为缓冲区的个数,full初值为1,empty初值为0

semaphore full=0,empty=1;
int buffer;//表示缓冲区
  • 1.
  • 2.
compute(){
   int nextc;
   while(1){
     计算出结果放入nextc;
     wait(empty);//空闲资源减1
     buffer=nextc;
     signal(full);//已用资源加1
   }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
print(){
  int nextp;
  while(1){
    wait(full);//已用缓冲区减1
    nextp=buffer;
    signal(empty);//空闲资源加1
    print nextp; 
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
main(){
  cobegin
    compute();print();
  coend
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

 不需要mutex互斥信号量,因为full,empty的最大值为1,且每个进程开始都有wait,所以不可能有两个进程同时访问缓冲区。

 

【多个生产者和消费者问题】

使用记录型信号量:

假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区

可利用互斥信号量mutex实现对缓冲池的互斥使用

利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量

【操作系统】进程:生成者-消费者问题_开发语言_02

当交换两个wait操作可能引起死锁。

当交换两个signal操作不会引起死锁。

使用管程:

【操作系统】进程:生成者-消费者问题_缓冲池_03

 

【操作系统】进程:生成者-消费者问题_开发语言_04

  

题目

【操作系统】进程:生成者-消费者问题_互斥_05

生产者消费者问题变体:

例:有三个进程PA,PB,PC协作解决文件打印问题。

PA将文件记录从磁盘读入内存的缓冲区1,每执行一次读一个记录;

PB将缓冲区1的内容复制到缓冲区2中,每执行一次复制一个记录;

PC将缓冲区2的内容打印出来,每执行一次打印一个记录,缓冲区的大小与记录大小一样。

请用信号量来保证文件的正确打印。

【操作系统】进程:生成者-消费者问题_缓冲池_06

 

【操作系统】进程:生成者-消费者问题_信号量_07

 注意:定义缓冲区;定义局部变量用于消费和生产

例:进程A1,A2,....,An1通过m个缓冲区向进程B1、B2、...、Bn2不断地发送消息。发送和接受工作遵循以下规则:

(1)每个发送进程一次发送一个消息,写入一个缓冲区,缓冲区大小与消息长度相同;

(2)对每个消息,B1、B2、...、Bn2都需各接受一次,读入自己的数据区内

(3)m个缓冲区都满时,发送进程等待;没有可读的消息时,接受进程等待