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

Давайте опустим вступление и обратимся к нашему примеру о «производителе» и «потребителе» из раздела о ждущих блокировках, но вместо ждущих блокировок будем использовать условные переменные. А затем уже обсудим вызовы.

/*

 * cp1.c

*/

#include

#include

int data_ready = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;

void* consumer(void *notused){

 printf("Это поток-потребитель...\n");

 while (1) {

  pthread_mutex_lock(&mutex);

  while (!data_ready) {

   pthread_cond_wait(&condvar, &mutex);

  }

  // Обработать данные

  printf("Потребитель: получил данные от производителя\n");

  data_ready = 0;

  pthread_cond_signal(&condvar);

  pthread_mutex_unlock(&mutex);

 }

}

void* producer (void *notused) {

 printf("Это поток-производитель...\n");

 while (1) {

  // Получить данные от оборудования

  // (мы имитируем это при помощи sleep(1))

  sleep(1);

  printf("Производитель: получил данные от h/w\n");

  pthread_mutex_lock(&mutex);

  while (data_ready) {

   pthread_cond_wait(&condvar, &mutex);

  }

  data_ready = 1;

  pthread_cond_signal(&condvar);

  pthread_mutex_unlock(&mutex);

 }

}

main() {

 printf(

  "Начало примера с производителем и потребителем...\n");

 // Создать поток-производитель и поток-потребитель

 pthread_create(NULL, NULL, producer, NULL);

 pthread_create(NULL, NULL, consumer, NULL);

 // Дать потокам немного повыполняться

 sleep(20);

}

Этот пример в значительной степени похож на программу с применением ждущей блокировки, с небольшими отличиями (мы добавили несколько вызовов printf(), а также функцию main(), чтобы программа могла работать!) Первое отличие, которое бросается в глаза, — здесь использован новый тип данных, pthread_cond_t. Это просто декларация для условной переменной; мы назвали нашу условную переменную condvar.

Следующее, что видно из примера, — это то, что структура «потребителя» идентична таковой в предыдущем примере с ждущей блокировкой. Мы заменили функции pthread_sleepon_lock() и pthread_sleepon_unlock() на стандартные мутекс-ориентированные версии (pthread_mutex_lock() и pthread_mutex_unlock()). Функция pthread_sleepon_wait() была заменена на функцию pthread_cond_wait().

Основное различие здесь состоит в том, что библиотека ждущих блокировок имеет скрытый внутренний мутекс, а при использовании условных переменных мутекс передается явно. Последний способ дает нам больше гибкости.

И, наконец, обратите внимание на то, что мы использовали функцию pthread_cond_signal() вместо функции pthread_sleepon_signal() (опять же, с явной передачей мутекса).

Функции phtread*_signal() и pthread*_broadcast()

В разделе о ждущих блокировках мы обещали обсудить различие между функциями pthread_sleepon_broadcast() и pthread_sleepon_signal(). Заодно поговорим и о различии между двумя аналогичными функциями, имеющими отношение к условным переменным: pthread_cond_signal() и pthread_cond_broadcast().

В двух словах, функция в варианте «signal» разблокирует только один поток. Например, если бы несколько потоков находилось в ожидании по функции «wait», и некий поток вызвал бы функцию pthread*_signal(), то был бы разблокирован только один из ждущих потоков. Который из них? Тот, у которого наивысший приоритет. Если имеется два или более потоков с одинаковым приоритетом, порядок «пробуждения» будет не определен. Применение же варианта pthread*_broadcast() приведет к тому что будут разблокированы все ожидающие потоки.

Разблокировать все потоки может показаться излишним. Но с другой стороны, разблокировать только один (причем случайный поток тоже не совсем корректно.

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

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

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

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

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

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

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

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

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