Параллельное и распределенное программирование на С++
Шрифт:
[EAGAIN] система испытывает недостаток в ресурсах (не имеется в виду память), необходимых для инициализации еще одной условной переменной;
[ENOMEM] для инициализации условной переменной недостаточно существующей памяти.
Функция pthread_cond_init может завершиться неудачно, если:
[EBUSY] реализация обнаружила попытку повторно инициализировать объект условной переменной, адресуемый параметром cond, которой был ранее инициализирован, но еще не разрушен;
[ EINVAL ] значение, заданное параметром аttr, недействительно.
Примеры
Условную
struct list {
pthread_mutex_t lm;
}
struct elt {
key k;
int busy;
pthread_cond_t notbusy;
}
/* Находим элемент списка и сохраняем его. */
struct elt * list_find (struct list *lp, key k) {
struct elt *ep;
pthread_mutex_lock (&lp->lm);
while ((ep = find_elt (1, к) ! = NULL) && ep->busy)
pthread_cond_wait (&ep->notbusy, &lp->lm);
if (ер != NULL) ep->busy = 1;
pthread_mutex_unlock (&lp->lm) ;
return (ер);
}
delete_elt (struct list *lp, struct elt *ep) {
pthread_mutex_lock (&lp->lm);
assert (ep->busy);
//... удаляем элемент ер из списка …
ep->busy = 0; /* Paranoid. */
(A) pthread_cond_broadcast (&ep->notbusy);
pthread_mutex_unlock (&lp->lm);
(B) pthread_cond_destroy (&rp->notbusy);
free (ер);
}
В этом примере условную переменную и ее элемент списка можно освободить (строка В) сразу после того, как все потоки, ожидающие соответствующего значения условной переменной, будут «разбужены» (строка А), поскольку мьютекс и этот код гарантируют, что никакой другой поток не сможет ссылаться на удаляемый элемент.
Замечания по использованию
Отсутствуют.
Логическое обоснование
С м. раздел «Логическое обоснование» в описании функции pthread_mutex_init .
Будущие направления
Отсутствуют.
Смотри также
pthread_cond_broadcast , pthread_cond_signal , pthread_cond_timedwait , то м Base Definidons стандартаШЕЕStd 1003.1-2001, <pthread.h>.
Последовательность внесения изменений
Функции впервые реализованы в выпуске Issue 5. Включены для согласования с расширение м POSIX Threads Extension.
Issue 6
Функции pthread_cond_destroy и pthread_cond_init от м ече н ы как часть опции Threads.
Раздел «Описание» был отредактирован путе м при м енения интерпретации IEEE PASC Interpretation 1003.1с #34.
В целях согласования со стандарто м ISO/IEC 9899:1999 в прототип функции pthread_cond_init было добавлено ключевое слово restrict.
pthread_cond_timedwait, pthread_cond_wait
Имя
pthread_cond_timedwait, pthread_cond_wait —
Синопсис
THR
#include <pthread.h>
int pthread_cond_timedwait ( pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
int pthread_cond_wait (pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
Описание
Функции pthread_cond_timedwait и pthread_cond_wait используются для блокирования потоков по условной переменной. Они вызываются с использованием мьютекса mutex , блокируемого вызывающим потоком; в противном случае результирующее поведение не определено.
Эти функции автоматически освобождают мьютекс mutex и обеспечивают блокирование вызывающего потока по условной переменной cond; «автоматически» здесь означает «автоматический доступ к мьютексу со стороны другого потока с последующим доступом к условной переменной». Другими словами, если какой-то другой поток может получить мьютекс после его освобождения вызывающим потоком, то результат последующего вызова функции pthread_cond_broadcast или pthread_cond_signal в этом (другом) потоке будет таким, как если бы он имел место после блокирования вызывающего потока.
При успешном выполнении мьютекс будет заблокирован, а владеть им будет вызывающий поток.
При использовании условных переменных всегда существует булев предикат, совместно используемый этими переменными, которые связаны с каждым ожидаемым условием. Это условие становится истинным, если поток должен продолжать выполнение. При использовании функций pthread_cond_timedwait или pthread_cond_wait возможны фиктивные запуски. Поскольку возврат из этих функций не подразумевает ничего, кроме оценки значения упомянутого выше предиката, он должен вычисляться после каждого такого выхода из функции.
Результат использования нескольких мьютексов для параллельно выполняемых операций pthread_cond_timedwait или pthread_cond_wait по одной и той же условной переменной не определен; другими словами, условная переменная связывается с уникальным мьютексом, когда поток ожидает заданного значения условной переменной, и это (динамическое) связывание завершится вместе с завершением ожидания.
Ожидание условия (синхронизированное или нет) представляет собой «точку отмены». Если статус возможности аннулирования дл я потока соответствует значению PTHREAD_CANCEL_DEFERRED, побочным эффектом действий, выполняемых по запросу на аннулирование во время ожидания условия будет повторный захват мьютекса перед вызовом первого обработчика запроса на отмену. Другими словами, результат будет выглядеть так, как если бы поток был разблокирован и получил воз м ожность выполниться до точки выхода из вызова функции pthread_cond_timedwait или pthread_cond_wait, но в этой точке «обнаружил» запрос на от м ену и в м есто возврата к инициатору вызова функции pthread_cond_timedwait или pthread_cond_wait приступил к выполнению действий по аннулированию, которые включают вызов обработчиков этого запроса.