【题目】
47.(8分)系统中有多个生产者进程和多个消费者进程,共享一个能存放1000件产品的环形缓冲区(初始为空)。当缓冲区未满时,生产者进程可以放入其生产的一件产品,否则等待;当缓冲区未空时,消费者进程可以从缓冲区取走一件产品,否则等待。要求一个消费者进程从缓冲区连续取走10件产品后,其他消费者进程才可以取产品。请使用信号量的P、V(wait( )、signal( ))操作实现进程间的互斥与同步,要求写出完整的过程,并说明所用信号量的含义和初值。
【答案要点】:
本题是一个生产者-消费者的变型,本题是多个生产者-多个消费者类型,生产者和消费者之间并不互斥访问缓冲区,但生产者和生产者之间,消费者和消费者之间要互斥访问缓冲区,并且本题的消费者一次需要取走10件产品,如果没有它会等待,而不是等到有了10件产品后,才进行取走操作。
本题的缓冲区B可描述为
buffer array [1000];
1)生产者之间设互斥信号量mutex1,消费者之间设互斥信号量metex2。
2)上述进程的同步问题,需设置3个信号量,其中empty对应空闲的缓冲单元,初值为1000;full对应缓冲区中待取走的产品数,初值为0;另外,还需定义2个整型变量in、out,分别用来指示下一个可存放产品的缓冲单元、下一个取走的缓冲单元,它们的初值均为0。过程如下:
buffer array [1000]; //存放产品的缓冲区
buffer nextp; //用于临时存放生产者生产的产品
buffer nextc [10]; //用于临时存放消费者取出的产品
semaphore empty = 1000; //空缓冲区的数目
semaphore full = 0; //满缓冲区的数目
semaphore mutex1 = 1; //用于生产者之间的互斥 s
emaphore mutex2 = 1; //用于消费者之间的互斥
int in = 0; //指示生产者的存位置
int out = 0; //指示消费者的取位置
Producer() //生产者进程
{
Produce an item put innextp; //生产一个产品,存在临时缓冲区
P(empty); //申请一个空缓冲区
P(mutex1); //生产者申请使用缓冲区
array[in]=nextp; //将产品存入缓冲区
in = (in+1)%1000;//指针后移
V(mutex1); //生产者缓冲区使用完毕,释放互斥信号量
V(full); //增加一个满缓冲区
}
Consumer() //消费者进程
{
P(mutex2); //消费者申请使用缓冲区
for(int i = 0;i<10;i++) //一个消费者进程需从缓冲区连续取走 10 件产品
{
P(full); //申请一个满缓冲区
nextc[i] = array[out];//将产品取出,存于临时缓冲区
out = (out+1)%1000;//指针后移
V(empty); //增加一个空缓冲区
}
V(mutex2); //消费者缓冲区使用完毕,释放互斥信号量
Consume the items innextc; //消费掉这 10 个产品
}