您的位置:首页 > 其它

生产者-消费者问题变形

2014-09-03 19:43 211 查看

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

注意:

生产者,消费者问题;

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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  生产者与消费者