Я проходил через this и this. В основном, они обсуждают, почему классический однопоточный потребительский дизайн производителя (с signal
и wait
не работает для многопрофильного сценария). У меня есть одно сомнение, которое прослушивал меня -pthread_mutex_wait несколько производителей и потребителей
Аргумент сделанный автором
Рассмотрим код ссылки
char queue[MAX]; //global
int head = 0, tail = 0; //global
struct cv not_full, not_empty;
struct lock qlock;
void produce(char data) {
acquire(&qlock);
if ((head + 1) % MAX == tail) {
wait(¬_full, &qlock); //line 1
}
queue[head] = data; //line 2
head = (head + 1) % MAX;
notify(¬_full);
release(&qlock);
}
char consume(void) {
acquire(&qlock);
if (tail == head) {
wait(¬_empty, &qlock);
}
e = queue[tail];
tail = (tail + 1) % MAX;
notify(¬_empty);
release(&qlock);
return e;
}
В приведенном выше коде, в случае двух производителя, line 1
будет woken up
в обоих нить производителя одним потребителем (когда очередь не заполнена). Таким образом, оба производителя могут добавить в очередь, что приведет к переполнению очереди.
Мои сомнения
a. Мы защищаем очередь с блокировкой мьютекса. Таким образом, даже если wait
разбудится на нескольких потоках производителей, только один производитель все равно будет блокировать мьютексы - поэтому логически для добавления в очередь будет принадлежать только один владелец. Потому что, когда мы выходим из wait
, у нас есть мьютекс, который будет приобретен.
Cavet
Я использую POSIX семафор, Cond вар в качестве ссылки. Тем не менее, я не вижу статьи, написанные с POSIX в качестве эталонного стандарта.
Вопрос
ли мое понимание wait
конкретно pthread_cond_wait
правильно? И с несколькими производителями целостность кода сохраняется.
вы на самом деле означает 'pthread_mutex_wait' или вы имеете в виду' pthread_cond_wait'? – UmNyobe
@UmNyobe: Правильно я бы отредактировал его. –
Я не уверен в вашем конкретном вопросе, но ваш код будет работать с несколькими производителями/потребителями, если вы преобразуете два оператора 'if' в операторы' while' и используете pthread_cond_broadcast в качестве примитива notify(). Но как есть, риск кода взрывается. – nos