Pthread_cond_broadcast(), pthread_cond_signal() - Паралельне та розподілене програмування на
Ці функції використовуються для розблокування потоків заблокованих за допомогою змінної умови.
pthread_cond_broadcast () дозволяє розблокувати всі потоки, заблоковані в даний момент з використанням змінної умови, заданої параметром cond.
pthread_cond_signal () використовується для розблокування принаймні одного з потоків, заблокованих з використанням умовної змінної, заданої параметром cond (якщо такі існують). Якщо з використанням цієї змінної умови заблоковано кілька потоків, то порядок розблокування буде визначено відповідно до їхньої стратегії планування. Коли кожен потік, розблокований в результаті виклику функції pthread_cond_broadcast() або pthread_cond_signal(), повернеться з викликаної ним функції pthread_cond_wait() або pthread_cond_timedwait(), цей потік отримає м'ютекс, з яким була викликана функція pthread_con. Розблоковані потоки будуть змагатися за м'ютекс відповідно до їхньої стратегії планування (якщо це має сенс), ніби кожен із них викликав функцію pthread_mutex_lock().
Функції pthread_cond_broadcast() та pthread_cond_signal() можуть бути викликані потоком, що володіє (або ні) в даний момент м'ютексом. При цьому потоки, що викликали функцію pthread_cond_wait() або pthread_cond_timedwait(), пов'язали під час очікування цей м'ютекс з умовною змінною. Однак, якщо необхідно забезпечити прогнозовану поведінку, цей м'ютекс може бути заблокований потоком, що викликав функцію pthread_cond_broadcast() або pthread_cond_signal().
Функції pthread_cond_broadcast() і pthread_cond_signal() не будуть мати результату, якщо в даний момент не існує потоків, заблокованих з використанням умовноїзмінною, заданою параметром cond.
При успішному завершенні функції pthread_cond_broadcast() та pthread_cond_signal() повертають нульове значення; в іншому випадку - код помилки, що позначає її характер.
pthread_cond_broadcast, pthread_cond_signal - функції розблокування потоків, заблокованих за допомогою змінної умови.
int pthread_cond_broadcast (pthread_cond_t *cond);
int pthread_cond_signal (pthread_cond_t *cond);
Функції pthread_cond_broadcast () і pthread_cond_signal () можуть завершитися невдало, якщо:
[EINVALJ значення, задане параметром cond, не посилається на ініціалізовану умовну змінну.
Ці функції не повертають код помилки [EINTR].
Зауваження щодо використання
Функція pthread_cond_broadcast () використовується при зміні стану загальної змінної ситуації, коли виконується відразу кілька потоків. Розглянемо завдання за участю одного «виробника» та кількох «споживачів», у якому «виробник» може вставити до списку кілька елементів, яких можуть отримувати доступ «споживачі» (по одному елементу за раз). Шляхом виклику функції pthread_cond_broadcast() "виробник" повідомляє про свою дію всіх "споживачів", які, можливо, перебувають у стані очікування, і, таким чином, при використанні мультипроцесора додаток може досягти більш високої пропускної спроможності. Крім того, функція pthread_cond_broadcast() дозволяє спростити реалізацію блокування читання-запису. Функція pthread_cond_broadcast () дуже корисна, коли записуючий потік звільняє блокування, і потрібно «запустити» всі потоки, що «читають», перебувають у стані очікування. Зрештою, цю широкомовну функцію можна використовувати у двофазному алгоритмі фіксаціїдля сповіщення всіх клієнтів про майбутню фіксацію транзакції.
Функцію pthread_cond_signal () небезпечно використовувати в обробнику сигналів, що викликається асинхронно. Навіть якщо це було б безпечно, мала б місце «перегонка» даних між перевірками булевої функції pthread_cond_wait(), яку неможливо ефективно усунути.
Отже, м'ютекси та змінні умов не підходять для звільнення очікуваного потоку шляхом сигналізації з коду оброблювача сигналів.
Декілька запусків за умовним сигналом
Для мультипроцесора, швидше за все, неможливо застосувати функцію pthread_cond_signal(), щоб уникнути розблокування кількох потоків, заблокованих за допомогою умовної змінної. Розглянемо, наприклад, наступну часткову реалізацію функцій pthread_cond_wait() та pthread_cond_signal(), що виконуються потоками в заданому порядку. Один потік намагається «дочекатися» потрібного значення умовної змінної, інший у своїй виконує функцію pthread_cond_signal(), тоді як третій потік перебуває у стані очікування.
value = cond->value; /* 1 */
pthread_mutex_unlock (mutex); /* 2 */
pthread_mutex_lock (cond-mutex); /* 10 */
if (value == cond->value) < /* 11 */
pthread_mutex_unlock (cond-mutex); /* 12 */