生产者-消费者问题变形

来源:互联网 发布:淘宝微淘首页 编辑:程序博客网 时间:2024/05/31 13:16


生产者与消费者问题变形:

注意:
生产者,消费者问题;
1.不论生产者,消费者的个数;
2.缓冲区单元个数有多个,则需要设置互斥信号量,如果只有一个,则可以不设置互斥信号量mutex。
3.empty+full=缓存区单元数;
4.不论生产者种类数;
5.如果多类消费者,则将full分为几类。

-----

(一)一类生产者,两类消费者问题:
(1)问题:
三个进程p1,p2,p3互斥的使用一个包含n个单元的缓冲区,p1每次用producer()生成一个正整数,并用put()送入到缓冲区的某个单元中;p2每次用getodd()从缓冲区取出一个奇数,并用countodd()计算奇数的个数;p3每次用geteven()从缓冲区取出一个偶数,并用counteven()统计偶数的个数。
/*注:题中给出的函数,均是封装好的,不需要在单独用p,v操作实现*/

(2)代码实现:
/*一类生产者,两类消费者*/
Semaphore mutex=1;//互斥信号量保护临界资源
Semaphore empty=n;//初始化时有n个单元
Semaphore odd=0; //装奇数的缓冲区个数
Semaphore even=0;//装偶数的缓冲区个数

//因为以前的一类消费者,分为两类,所以将full分为两份。

main(){
 p1();
 p2();
 p3();
}
/*进程p1,即生产者*/
p1(){
 while(1){
  number=producer();//产生一个数

  p(empty);//接收到放数的消息

  p(mutex);//将数放入缓冲区
  put();
  v(mutex);

  if(number%2==0)
  V(even);//通知偶数接收者取数
  else
  V(odd);//通知奇数接收者取数
 }
}

/*进程p2,即消费者一,即奇数接收者*/
P2(){
 
 while(1){
  p(odd);

  p(mutex);//取奇数
  getodd();
  v(mutex);

  v(empty);//通知生产者可以放数了。
  countOdd();
 }
}

/*进程p3,即消费者二,即偶数接收者*/
p3(){
 
 while(1){
  p(even);//接收到取偶数的消息
  p(mutex);//取偶数
  geteven();
  v(mutex);

  v(empty);
  counteven();
 }
}

(3)分析:
一类生产者,二类消费者,只不过生产者进程中根据条件(if)通知(V操作)相应的消费者取相应的产品。
将信号量full,分为几类。

---------

(二)生产者-》缓冲区1-》消费者1-》缓冲区2-》消费者2
(即消费者又是另一个缓冲区的生产者)

(1)问题:
P1进程放数-》缓冲区1-》P2从缓冲区1取数,并复制到-》缓冲区2——》从2取数。
注:每个缓冲区的大小为一个单元。
(2)实现:
Semaphore empty1=1;
Semaphore empty2=1;
Semaphore full1=0;
Semaphore full2=0;

main(){
 p1();p2();p3();
}

p1(){
 while(1){
  产生一个数;
  p(empty1);
  数放到缓冲区1;
  v(full1);//通知p2取数
 }
}

p2(){
 while(1){
  p(full);
  从缓冲区1取数;
  v(empty1);//通知缓冲区1放数

  p(empty2);
  向缓冲区2放数;
  v(full2);//通知p3取数。
 }
}

p3(){
 while(1){
  p(full2);
  从缓冲区2取数;
  v(empty2);//通知p2向缓冲区2放数

 }
}

--------

(三)放水果,取水果问题:

(1)问题:
有一个盘子,最多可以容纳两个水果,每次只能向其中放或者拿一个水果。爸爸向其中放apple,妈妈向其中放orange,儿子只拿orange,女儿只拿apple.

(2)分析:
empty=2;//表示可以放入的水果数

//将full(临界单元中的商品数)分为两类,apple,和orange
apple=0;//表示盘子中已经放入的苹果数
orange=0;//表示盘子中放入的橘子数
mutex=1;//互斥信号量,保证不能取水果,放水果同时进行。因为临界资源的单元数>1,所以要防止同时进行。

(3)代码实现:

Semaphore empty=2;//临界资源的最大容量
Semaphore mutex=1;//临界资源容量>1,所以需要防止取放同时进行。
Semaphore apple=0;//将临界资源中的产品数full,分为临界资源中的苹果数和橘子数
Semaphore orange=0;

main(){
 father();mather();son();daughter();
}

father(){
 p(emtpy);

 p(mutex);
 放入一个apple;
 v(mutex);

 V(apple);
}

mather(){
 p(emtpy);

 p(mutex);
 放入一个orange;
 v(mutex);

 V(orange);
}

son(){
 
 p(orange);

 p(mutex);
 从盘子中取橘子;
 v(mutex);

 v(empty);
}

daughter(){
 
 p(apple);

 p(mutex);
 从盘子中取苹果;
 v(mutex);
 v(empty);
}

-----

(1)问题:
有一个盘子,只能放一个水果,爸爸每次往其中放apple,妈妈每次往盘子放orange,儿子每次取orange,女儿每次取apple,

(2)分析:
只有一个临界单元,所以不会发现同时取放。所以不需要互斥信号量。

(3)实现:
Semaphore empty=1;
Semaphore apple=0;
Semaphore orange=0;

main(){
 father();mather();
 son();daughter();
}

father(){
 p(empty);
 放apple;
 v(apple);
}

mather(){
 p(empty);
 放orange;
 v(orange);
}

son(){
 p(orange);
 取orange;
 v(empty);
}
daughter(){
 p(apple);
 取apple;
 v(empty);
}


0 0
原创粉丝点击