Многопоточность: классический продюсер потребительский алгоритм

StackOverflow https://stackoverflow.com/questions/4058594

Вопрос

Что-то, чего я не понимаю о классическом алгоритме для продюсер-потребительской проблемы (от Wikipedia :)

SEMAPHORE MUTEX = 1 SEMAPHORE FLAILCOUNT = 0 SEMAPHORE joycount = Buffer_Size Procenter Production () {While While (true) {item = productionem () down (joincount) down (mutex) putitemintobuffer (элемент) вверх (mutex) up (fillcount) up ( Fillcount) // Потребитель может не закончить перед производителем. } Процедура Потребитель () {while (true) {down (fillcount) down (mutex) item = ustheriTemfrombiffer () up (mutex) (jugcountcount) consumeitem (item)}}

Отмечу, что как продюсеры, так и потребители блокируют «MUTEX» перед возобновлением буфера, и разблокировать его после этого. Если это так, то есть только один поток обращается к буферу в любой момент, я на самом деле не вижу, как вышеупомянутое алго отличается от простого решения, которое влечет за собой только охрану Mutex на буфер:

SEMAPHORE MUTEX = 1 Производитель процедуры () {Whaue (true) {item = productiTem () flag = true while (flag) {down (mutex), если (flagernotfulll ()) {putitemintobuffer (item) flag = fals = false} (mutex) }}} Процедура Потребитель () {While (True) {flag = true while withy (flag) {down (mutex), если (buffernoTempty ()) {item = flageletimfrombuffer () flag = false} (Mutex)} ConsumeItem (item) }}

Только что я могу думать о том, что требует, используя семафоры «FillCount» и «jogryCount» планирование.

Может быть, первое вол в том, чтобы убедиться, что в состоянии, где 5 потребителей ждут на пустом буфере (нулевой «Fillcount»), уверены, что когда приходит новый продюсер, он пройдет мимо его «вниз (jointCount)» Выражение быстро и быстро получите «Mutex».

(В то время как в другом решении потребители не понравятся, получают только «Mutex» только для того, чтобы отказаться от него, пока новый производитель не получит его и вставит элемент).

Я прав? Я что-то упускаю?

Это было полезно?

Решение

Если в буфере нет сообщений, потребитель снинется на мьютекс, проверяет буфер, обнаружил, что он пуст, вверх по мьютексу, цикл обратно и немедленно повторите процесс. По простым условиям, потребители и производители застряли в оживленных петель, которые разворачивают 100% CPU Core. Это не просто теоретическая проблема. Вы вбередитесь, что вентилятор вашего компьютера начинает вращаться каждый раз, когда вы запускаете свою программу.

Другие советы

Концепция отверстий производителя / потребительской узор состоит в том, что Общий ресурс (буфер) доступен только в том случае, если определенные критерии будут выполнены. Отказ И не использовать ненужные циклы ЦП, чтобы убедиться, что они встречаются.

Потребитель:

  • Подождите, если нечего потреблять (=> пустой буфер).

Режиссер:

  • Подождите, если в буфере недостаточно места.

И для обоих очень важно отметить:

  • Ждать! = Спин ждать

Есть больше, чем просто фиксировка буфера.

То fillCount Семафор в первой программе - приостановить потребителя (ы), когда ничего не осталось потреблять. Без этого вы постоянно выбираете буфер, чтобы увидеть, есть ли что-нибудь, чтобы получить, и это довольно расточительно.

Аналогично, то emptyCount Семафор приостанавливает производителю, когда буфер заполнен.

Существует голодная проблема, если участвует более одного потребителя. В последнем примере потребительские проверки для элемента в петле. Но к тому времени, когда он собирается попробовать еще раз, какой другой потребитель может «украсть» его предмет. И в следующий раз снова и снова. Это не приятно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top