它们应满足同步条件:
①任一时刻所有生产者存放产品的单元数不能超过缓冲区的总容量(N)。
②所有消费者取出产品的总量不能超过所有生产者当前生产产品的总量。设缓冲区的编号为0~N-1,in和out分别是生产者进程和消费者进程使用的指针,指向下面可用的缓冲区,初值都是0。
设置三个信号量
生产者进程Producer
while(TRUE) {
P(Empty);
P(Mutex);
产品送往buffer(in);
in=(in+1)mod N;
/*以N为模*/
V(Mutex);
V(Full);
}
消费者进程Producer
while(TRUE) {
P(Full);
P(Mutex);
产品被取走buffer(out);
out=(out+1)mod N;
/*以N为模*/
V(Mutex);
V(Empty);
}
应注意
①在每个程序中必须先做P(mutex),后做V(mutex),二者要成对出现。
②对同步信号量full和empty的P, V操作同样必须成对出现,但它们分别位于不同的程序中。
③无论在生产者进程中还是在消费者进程中,两个 P 操作的次序不能颠倒 。
较大的疑惑在于③。
当消费者进程中的P(Mutex)操作在先,P(Full)操作在后,若先执行消费者进程,则Mutex-1,为0,且Full为0(一个资源也没有),则无法进入缓冲区获得资源;同时,因为Mutex为0,生产者进程无法进入缓冲区投放资源(无论生产者进程的两个P操作顺序如何),无法投放资源,则消费者进程无法往下执行,故而形成死锁。
当生产者进程中的P(Mutex)操作在先,P(Full)操作在后,消费者进程中的P(Full)操作在先,P(Mutex)操作在后,若生产者进程往缓冲区投放资源,直至投满缓冲区,且之后消费者进程刚完成P(Full)操作,就被生产者抢了CPU,完成了P(Mutex)操作,但此时由于缓冲区已满,故无法再投放资源,而消费者进程则由于生产者进入了临界区,故无法到临界区取资源,也无法继续往下执行,故而形成死锁。
所以无论在生产者进程中还是在消费者进程中,两个 P 操作的次序不能颠倒 。