Вход/Регистрация
Параллельное и распределенное программирование на С++
вернуться

Хьюз Камерон

Шрифт:

Нет никакой опасности в разрушении инициализированной условной переменной, по которой не заблокирован в данный момент ни один поток. Попытка же разрушить условную переменную, по которой заблокированы в данный момент другие потоки, может привести к неопределенному поведению.

Функция pthread_cond_init используется для инициализации условной пере м енной, адресуе м ой пара м етро м cond, объекто м атрибутов, адресуе м ы м пара м етро м attr. Если пара м етр attr со д ержит значение NULL, для инициализации применяются атрибуты условной переменной, действующие по умолчанию, т.е. результат в этом случае равносилен передаче адреса объекта, содержащего стандартные атрибуты условной пере м енной. После успешной инициализации Условная Переменная становится инициализированной.

Для осуществления синхронизации используется только сама условная переменная cond. Результат ссылки на копии пере м енной cond в обращениях к функциям pthread_cond_wait, pthread_cond_timedwait, pthread_cond_signal, pthread_cond_broadcast и pthread_cond_destroy неопределен. Попытка инициализировать уже инициализированную условную переменную приведет к неопределенному поведению.

Если атрибуты условной переменной, действующие по умолчанию, заранее определены, для инициализации условных переменных, которые создаются статически, можно использовать макрос PTHREAD_COND_INITIALIZER. Результат в это м случае эквивалентен дина м ической инициализации путе м вызова функции pthread_cond_init с пара м етро м attr, равны м значению NULL, но без проверки на наличие ошибок.

Возвращаемые значения

При успешно м завершении функции pthread_cond_destroy и pthread_cond_init возвращают нулевое значение; в противно м случае— код ошибки, обозначающий ее характер.

Проверка на наличие ошибок с кодами [EBUSY] и [EINVAL] реализована так (если реализована вообще), как будто она выполняется в самом начале работы каждой функции, и код ошибки в случае ее обнаружения возвращается до модификации состояния условной переменной, заданной параметром cond.

Ошибки

Функция pthread_cond_destroy может завершиться неудачно, если:

[EBUSY] реализация обнаружила попытку разрушить объект, адресуемый параметром cond, который относится к другому потоку (например, при использовании в функциях pthread_cond_wait или pthread_cond_timedwait );

[EINVAL] значение, заданное пара м етро м cond, недействительно.

Функция pthread_cond_init завершится неудачно, если:

[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 (ер);

}

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

  • Читать дальше
  • 1
  • ...
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: