Ключевое утверждение в описании, которое относится к вашему ответу: «У нас есть буфер фиксированного размера.»
Чтобы ответить на ваш вопрос, давайте сначала предположим, что буфер может расширяться, чтобы вместить столько элементов, сколько необходимо, или, другими словами, буфер может увеличиваться до неограниченного размера. В этом случае единственная синхронизация, которая должна произойти между производителями и потребителями (кроме блокировки мьютекса, чтобы гарантировать, что вы не повредите элементы в критической секции), будет гарантировать, что потребители потребляют элементы только после * 1006. * они были произведены производителем. Вы можете решить эту проблему с помощью мьютекса и одного семафора. Вот код, который я позаимствовал и изменил по ссылке, которой вы поделились:
Производитель
do {
//produce an item
wait(mutex);
//place in buffer
signal(mutex);
signal(full);
} while (true);
Потребитель
do {
wait(full);
wait(mutex);
//remove item from buffer
signal(mutex);
//consume item
} while (true);
Как вы можете видеть выше, производитель всегда может добавлять вещи в очередь (кроме случаев, когда удерживается мьютекс), и ему не нужно ждать, пока потребители что-нибудь потребят, потому что буфер никогда не заполнится, даже если если потребители не потребляют предметы. С другой стороны, потребители не могут ничего потреблять, пока производители не произвели товары.
Чтобы ответить на ваш вопрос, вам нужно сосредоточиться на утверждении: «У нас есть буфер фиксированного размера». Это меняет проблему. Поскольку буфер больше не может расти до неограниченного размера, вам нужно заставить производителей ждать, когда буфер заполнится, прежде чем они смогут добавить больше вещей в буфер . Вот почему вам нужен второй семафор. Потребители должны не только ждать производителей, но теперь производители должны ждать потребителей. Вы заставляете производителей ждать потребителей, заставляя их звонить wait
на семафор, который только потребители называют signal
на
.
Вы не можете сделать это только с одним семафором, потому что условия, когда производитель должен ждать, отличаются от условий, когда потребитель должен ждать. Поскольку они должны иметь возможность уменьшать и перемещаться за семафором в разных условиях, вы не можете использовать один и тот же семафор для обоих.