使用此Semaphore算法解决Producer-Consumer问题,其中信号量按缓冲区大小递减,然后信号量递减1表示临界区。
如果这些操作连续连续发生,为什么递减1(互斥锁)然后减小缓冲区大小是不正确的?
我知道生产者和消费者都会在创建死锁的同时进入休眠状态,但为什么这个次要的开关导致整个算法失败?
BufferSize = 3;
semaphore mutex = 1; // Controls access to critical section
semaphore empty = BufferSize; // counts number of empty buffer slots
semaphore full = 0; // counts number of full buffer slots
Producer()
{
int widget;
while (TRUE) { // loop forever
make_new(widget); // create a new widget to put in the buffer
down(&empty); // decrement the empty semaphore
down(&mutex); // enter critical section
put_item(widget); // put widget in buffer
up(&mutex); // leave critical section
up(&full); // increment the full semaphore
}
}
Consumer()
{
int widget;
while (TRUE) { // loop forever
down(&full); // decrement the full semaphore
down(&mutex); // enter critical section
remove_item(widget); // take a widget from the buffer
up(&mutex); // leave critical section
up(&empty); // increment the empty semaphore
consume_item(widget); // consume the item
}
}
代码来源: Resource
答案 0 :(得分:3)
它不正确,因为如果生产者通过wait(互斥)进入代码段然后它发现没有空块,那么它必须等待空信号量。在消费者试图输入的同时,必须等待互斥锁,因为生产者锁定了互斥锁。因此,生产者正在等待消费者消费而消费者正在等待生产者发出信号(互斥) 对于互斥锁和信号量的原始排列情况并非如此,其中生产者或消费者只有在减少信号量值时才允许等待互斥锁。因此没有死锁。