对生产者消费者信号量顺序的一个小改动
A small change to producer consumer semaphores order
这是经典的生产者消费者问题解决方案:
semaphore mutex = 1
semaphore fillCount = 0
semaphore emptyCount = BUFFER_SIZE
procedure producer() {
while (true) {
item = produceItem()
down(emptyCount)
down(mutex)
putItemIntoBuffer(item)
up(mutex)
up(fillCount)
}
}
procedure consumer() {
while (true) {
down(fillCount)
down(mutex)
item = removeItemFromBuffer()
up(mutex)
up(emptyCount)
consumeItem(item)
}
}
我的问题是,如果我们交换消费者或生产者中的最后两个信号量顺序,会有什么影响?
例如,如果消费者的代码变为:
procedure consumer() {
while (true) {
down(fillCount)
down(mutex)
item = removeItemFromBuffer()
up(emptyCount)
up(mutex)
consumeItem(item)
}
}
在这个简单的例子中,结果是一样的,你不会遇到饥饿或死锁(即使 consumer
的第二个版本绝对是一个不好的做法)。
考虑一个更复杂的情况(这不应该发生),您有错误的消费者并且您在 up(emptyCount)
和 up(mutex)
之间有一些代码,如下所示:
up(emptyCount)
// time-consuming code
up(mutex)
在这种情况下,您可能会有更多 producer
等待 mutex
的发布,这是没有必要的。
现在考虑更糟糕的情况,您必须在这 2 条指令之间处理另一个信号量:在最坏的情况下,它可能导致饥饿。
这是经典的生产者消费者问题解决方案:
semaphore mutex = 1
semaphore fillCount = 0
semaphore emptyCount = BUFFER_SIZE
procedure producer() {
while (true) {
item = produceItem()
down(emptyCount)
down(mutex)
putItemIntoBuffer(item)
up(mutex)
up(fillCount)
}
}
procedure consumer() {
while (true) {
down(fillCount)
down(mutex)
item = removeItemFromBuffer()
up(mutex)
up(emptyCount)
consumeItem(item)
}
}
我的问题是,如果我们交换消费者或生产者中的最后两个信号量顺序,会有什么影响?
例如,如果消费者的代码变为:
procedure consumer() {
while (true) {
down(fillCount)
down(mutex)
item = removeItemFromBuffer()
up(emptyCount)
up(mutex)
consumeItem(item)
}
}
在这个简单的例子中,结果是一样的,你不会遇到饥饿或死锁(即使 consumer
的第二个版本绝对是一个不好的做法)。
考虑一个更复杂的情况(这不应该发生),您有错误的消费者并且您在 up(emptyCount)
和 up(mutex)
之间有一些代码,如下所示:
up(emptyCount)
// time-consuming code
up(mutex)
在这种情况下,您可能会有更多 producer
等待 mutex
的发布,这是没有必要的。
现在考虑更糟糕的情况,您必须在这 2 条指令之间处理另一个信号量:在最坏的情况下,它可能导致饥饿。