我试图表明生产者/消费者问题的以下解决方案不起作用,通过显示当消费者处于M1的开头时,存在无法将项目出列的情况在有限的时间内,和/或存在生产者处于L2的开头的情况,并且它将无法在有限的时间内将项目排队。我只是找不到任何证明它的例子。
该算法假设有10个生产者,10个消费者,缓冲区大小为10。
nf = 0; // counting semaphore, # of items in queue
bm = 1; // binary semaphore, ensures mutex
生产者
L1: Produce(item);
L2: P(bm);
If (queue_is_full) {
V(bm);
GoTo L2;
} else {
Enqueue(item);
V(bm);
V(nf);
GoTo L1;
}
消费
M1: P(nf);
P(bm);
Dequeue(item);
V(bm);
Consume(item);
GoTo M1;
答案 0 :(得分:0)
如果我的理解是正确的,P(x)是锁定直到x!= 0而v(x)总是x ++。
在上面的代码中M1: P(nf);
只会让消费者通过队列中的项目是否可用。然后总是获取并释放bm上的锁定。所以我很确定代码不会与其他消费者或生产者陷入僵局。
在生产者中,它获得了bm,然后在列表上运行。它在v(bm)之前没有获得任何其他锁,并且它在两个分支中执行v(bm),因此可以保证发生。由于v(bm)最终会发生,消费者最终可能会消耗一个项目。在v(bm)之后,保证v(nf),因此当产生项目时,一个消费者将尝试最终消费它。
因此代码看起来很好,除非有像listcapacity == 0这样愚蠢的东西。
如果消费者做了P(bm) - >,那么会出现问题。 P(NF) - > V(bm),但上面的代码看起来很好