вызывать pthread_cond_broadcast с удержанным мьютексом или нет? - PullRequest
8 голосов
/ 09 июля 2009

С pthread_cond_t мы должны связать мьютекс, сигнализируя о состоянии, которое я видел, например,

pthread_mutex_lock(&mutex);

//code that makes condition true

pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);

и

pthread_mutex_lock(&mutex);

//code that makes condition true

pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cond);

Какой путь правильный? (Это имеет значение?)

1 Ответ

14 голосов
/ 09 июля 2009

Зависит от того, что делают приемники (и любые другие источники).

Во втором примере кода, возможно, что между разблокировкой и трансляцией возникнет куча других потоков, которые выполнят некоторую комбинацию вещей, которая снова сделает условие ложным. Тогда вы будете бессмысленно вещать. И у вас не обязательно будет такой же набор официантов, какой был при смене условия, которое может повлиять или не повлиять на ваш дизайн.

Приличный приемник не должен волноваться, если он проснулся и условие ложное, особенно если вы используете трансляцию. До тех пор, пока за каждым изменением условия на «истина» в конечном итоге следует широковещательная рассылка, я почти уверен, что с соответствующим образом написанными приемниками можно передавать произвольную переменную условия с блокировкой или без нее.

Так что я не думаю, что это действительно имеет значение, но лично я бы транслировал с зажатой блокировкой, хотя бы чтобы не волноваться об этом. «Атомное изменение и сигнал» может упростить диаграмму состояний на вашей доске по сравнению с «изменением ... через некоторое время, сигнал».

Оба являются правильными (в отличие от ожидания без мьютекса, что недопустимо), но я не думаю, что было бы слишком сложно придумать варианты использования, которые могут пойти не так во втором случае, который не пойдет неправильно в первом. Возможно, им придется привлекать официантов, делающих немного необычные вещи.

Спецификация довольно загадочно гласит: «если требуется предсказуемое поведение планирования, этот мьютекс должен быть заблокирован потоком, вызывающим pthread_cond_broadcast () или pthread_cond_signal ().»

http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

...