Читаем Введение в QNX/Neutrino 2 полностью

Поэтому мы должны думать, где имеет смысл использовать какой вариант. Очевидно, что если у вас только один ждущий поток, как у нас и было во всех вариантах «потребителя», функция pthread*_signal() прекрасно справится — будет разблокирован один поток, и как раз тот, который нужно (потому что других просто нет).

В ситуации с несколькими потоками в первую очередь следует выяснить: а почему они ждут? Обычно на этот вопрос есть два ответа:

• все потоки рассматриваются как эквивалентные и реально образуют пул доступных потоков, готовых к обработке некоторого запроса;

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

В первом случае мы можем представить себе, что код всех потоков имеет примерно следующий вид:

/*

 * cv1.c

*/

#include

#include

pthread_mutex_t mutex_data = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cv_data = PTHREAD_COND_INITIALIZER;

int data;

thread1() {

 for (;;) {

  pthread_mutex_lock(&mutex_data);

  while (data == 0) {

   pthread_cond_wait(&cv_data, &mutex_data);

  }

  // Сделать что-нибудь

  pthread_mutex_unlock(&mutex_data);

 }

}

В этом случае абсолютно неважно, который именно из потоков получит данные — главное, чтобы хотя бы один сделал это и произвел над этими данными необходимые действия.

Однако, если ваш код подобен приведенному ниже, все будет несколько по-иному:

/*

 * cv2.c

*/

#include

#include

pthread_mutex_t mutex_xy = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cv_xy = PTHREAD_COND_INITIALIZER;

int x, y;

int isprime(int);

thread1() {

 for (;;) {

  pthread_mutex_lock(&mutex_xy);

  while ((x > 7) && (y != 15)) {

   pthread_cond_wait(&cv_xy, &mutex_xy);

  }

  // Сделать что-нибудь

  pthread_mutex_unlock(&mutex_xy);

 }

}

thread2() {

 for (;;) {

  pthread_mutex_lock(&mutex_xy);

  while (!isprime(x)) {

   pthread_cond_wait(&cv_xy, &mutex_xy);

  }

  // Сделать что-нибудь

  pthread_mutex_unlock(&smutex_xy);

 }

}

thread3() {

 for (;;) {

  pthread_mutex_lock(&mutex_xy);

  while (x != y) {

   pthread_cond_wait(&cv_xy, &mutex_xy);

  }

  // Сделать что-нибудь

  pthread_mutex_unlock(&mutex_xy);

 }

}

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

Это в полной мере отражает второй вариант ответа на наш вопрос «а почему они ждут?» Так как все потоки все ждут соблюдения различных условий (поток thread1() ждет, пока значение x не станет меньше или равно 7, или пока значение у не станет равным 15, поток thread2() ждет, пока значение x не станет простым числом, а поток thread3() ждет, пока x не станет равным у), у нас нет никакого выбора, кроме как «разбудить» все потоки «одновременно».

Ждущие блокировки в сравнении с условными переменными

Ждущие блокировки имеют одно основное преимущество в сравнении с условными переменными. Предположим, что вам надо синхронизировать множество объектов. Используя условные переменные, вы бы ассоциировали с каждым объектом отдельную условную переменную — если бы у вас было M объектов, вы, скорее всего, определили бы M условных переменных. При применении же ждущих блокировок соответствующие им условные переменные создаются динамически по мере постановки потоков на ожидание, поэтому в этом случае на M объектов и N блокированных потоков у вас было бы максимум N, а не M условных переменных.

Однако, условные переменные более универсальны, чем ждущие блокировки, и вот почему:

1. Ждущие блокировки в любом случае основаны на условных переменных.

2. Мутексы ждущих блокировок скрыты в библиотеке; условные переменные позволяют вам задавать его явно.

Первый пункт сам по себе достаточно убедителен. :-) Второй, однако, имеет еще и практический смысл. Когда мутекс скрыт в библиотеке, это означает, что он может быть только один на процесс, независимо от числа потоков в этом процессе или от количества переменных. Это может быть сильно ограничивающим фактором, особенно если принять во внимание, что вам придется использовать один-единственный мутекс для синхронизации доступа всех имеющихся потоков в процессе ко всем нужным им переменным!

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных