Читать «UNIX: взаимодействие процессов» онлайн - страница 118
Уильям Ричард Стивенс
int dosignal;
Pthread_mutex_lock(nready.mutex);
dosignal = (nready.nready == 0);
nready.nready++;
Pthread_mutex_unlock(&nready.mutex);
if (dosignal)
Pthread_cond_signal(&nready.cond);
Здесь мы отправляем сигнал условной переменной только после разблокирования взаимного исключения. Это разрешено стандартом Posix: поток, вызывающий pthread_cond_signal, не обязательно должен в этот момент блокировать связанное с переменной взаимное исключение. Однако Posix говорит, что если требуется предсказуемое поведение при одновременном выполнении потоков, это взаимное исключение должно быть заблокировано процессом, вызывающим pthread_cond_signal.
7.6. Условные переменные: время ожидания и широковещательная передача
В обычной ситуации pthread_cond_signal запускает выполнение одного потока, ожидающего сигнал по соответствующей условной переменной. В некоторых случаях поток знает, что требуется пробудить несколько других процессов. Тогда можно воспользоваться функцией pthread_cond_broadcast для пробуждения всех процессов, заблокированных в ожидании сигнала данной условной переменной.
ПРИМЕЧАНИЕ
Пример ситуации, в которой требуется возобновление выполнения нескольких процессов, появится в главе 8, когда мы будем обсуждать задачу с несколькими считывающими и записывающими процессами. Когда записывающий процесс снимает блокировку, он должен разбудить все ждущие считывающие процессы, поскольку одновременное считывание в данном случае разрешено.
Альтернативным (и более безопасным) методом является использование широковещательной передачи во всех тех случаях, когда требуется использование сигналов. Сигнал является оптимизацией для тех случаев, когда известно, что все ожидающие процессы правильно написаны и требуется разбудить только один из них, и какой именно будет разбужен, значения не имеет. Во всех других ситуациях следует использовать широковещательную передачу.
#include <pthread.h>
int pthread_cond_broadcast(pthread_cond_t
int pthread_cond_timedwait(pthread_cond_t
/* Функции возвращают 0 в случае успешного завершения, положительный код Еххх — в случае ошибки */
Функция pthread_cond_timedwait позволяет установить ограничение на время блокирования процесса. Аргумент
struct timespec {
time_t tv_sec; /* секунды */
long tv_nsec; /* наносекунды */
};
Эта структура задает конкретный момент системного времени, в который происходит возврат из функции, даже если сигнал по условной переменной еще не будет получен. В этом случае возвращается ошибка с кодом ETIMEDOUT.
Эта величина представляет собой абсолютное значение времени, а не промежуток. Аргумент