The code From wikipedia for producer consumer queue with a single producer and a single consumer is:
semaphore fillCount = 0; // items produced
semaphore emptyCount = BUFFER_SIZE; // remaining space
procedure producer()
{
while (true)
{
item = produceItem();
down(emptyCount);
putItemIntoBuffer(item);
up(fillCount);
}
}
procedure consumer()
{
while (true)
{
down(fillCount);
item = removeItemFromBuffer();
up(emptyCount);
consumeItem(item);
}
}
it is stated there that
The solution above works fine when there is only one producer and consumer.
When there are more producers/consumers, the pseudocode is the same, with a mutex guarding the putItemIntoBuffer(item);
and removeItemFromBuffer();
sections:
mutex buffer_mutex; // similar to "semaphore buffer_mutex = 1", but different (see notes below)
semaphore fillCount = 0;
semaphore emptyCount = BUFFER_SIZE;
procedure producer()
{
while (true)
{
item = produceItem();
down(emptyCount);
down(buffer_mutex);
putItemIntoBuffer(item);
up(buffer_mutex);
up(fillCount);
}
}
procedure consumer()
{
while (true)
{
down(fillCount);
down(buffer_mutex);
item = removeItemFromBuffer();
up(buffer_mutex);
up(emptyCount);
consumeItem(item);
}
}
My question is, why isn't the mutex required in the single producer single consumer case?
consider the following:
- 5 items in a queue allowing 10 items.
- Producer produces an item , decrements the empty semaphore (and succeeds), then starts putting the item into the buffer, and is not finished
- Consumer decrements the fill semaphore, then starts to remove item from buffer
- unexpected. Trying to remove item from buffer (3) while putting item to buffer (2)
Why does what i described not happen?