Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform | страница 55



и pthread_sleepon_broadcast() мы еще вернемся в разговоре об условных переменных.

Условные переменные

Условные переменные (или «condvars») очень похожи на ждущие блокировки, которые мы рассматривали выше. В действительности, ждущие блокировки — это надстройка над механизмом условных переменных, и именно поэтому в таблице, иллюстрировавшей использование ждущих блокировок, у нас встречалось состояние CONDVAR. Функция pthread_cond_wait() точно так же освобождает мутекс, ждет, а затем повторно блокирует мутекс, аналогично функции pthread_sleepon_wait().

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

>/*

> * 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.

Следующее, что видно из примера, — это то, что структура «потребителя» идентична таковой в предыдущем примере с ждущей блокировкой. Мы заменили функции