Поскольку такая очередь обычно будет реализована в виде циклической очереди.Продюсер будет писать в конец очереди, а потребитель читает из головы.Они никогда не обращаются к одной и той же памяти в одно и то же время.
Идея заключается в том, что и потребитель, и производитель могут отслеживать положение хвоста / головы независимо друг от друга.
Рассмотрим следующий псевдокод:
T data[BUFFER_SIZE];
int producerPtr = 0, consumerPtr = 0;
void putItemIntoBuffer(Item item)
{
data[producerPtr] = item;
producerPtr = (producerPtr + 1) % BUFFER_SIZE;
}
Item removeItemFromBuffer(void)
{
Item item = data[consumerPtr ];
consumerPtr = (consumerPtr + 1) % BUFFER_SIZE;
return item;
}
И consumerPtr
, и producerPtr
могут быть равны только в том случае, если очередь заполнена или пуста, и в этом случае эти функции не будут вызываться, поскольку выполняющийся процесс останется заблокированным на семафоре.
Можно сказать, что семафоры используются в качестве механизма передачи сообщений, позволяя другой стороне увеличивать свой указатель, синхронизируя это.
Теперь, если у вас есть несколько процессов на одной стороне, эта сторона должна будетинкрементно выполнять инкрементное копирование и копирование данных, для этого необходим мьютекс, но только для стороны, в которой есть несколько процессов, например, для очереди с несколькими производителями и очередями с несколькими потребителями, вы можете использовать 2 отдельных мьютекса для уменьшения конкуренции.