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

Кёртен Роб

Шрифт:

• Он выполняет функцию «места, где происходит синхронизация со ждущей блокировкой». Более формально говоря, адрес переменной data_ready используется как уникальный идентификатор объекта, по которому осуществляется ждущая блокировка. Мы запросто могли бы применить «

(void*)12345
» вместо «
&data_ready
» — библиотеке ждущих блокировок все равно, что это за идентификатор, лишь бы он был уникален и корректно использовался. Использование же в качестве идентификатора адреса переменной есть надежный способ сгенерировать уникальный номер, поскольку не бывает же двух переменных с одинаковым адресом!

• К обсуждению различий между функциями pthread_sleepon_signal и pthread_sleepon_broadcast мы еще вернемся в разговоре об условных переменных.

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

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

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

/*

 * cp1.c

*/

#include <stdio.h>

#include <pthread.h>

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.

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

  • Читать дальше
  • 1
  • ...
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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