Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform | страница 55
Условные переменные
Условные переменные (или «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.
Следующее, что видно из примера, — это то, что структура «потребителя» идентична таковой в предыдущем примере с ждущей блокировкой. Мы заменили функции