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

Шрифт
Интервал

Причина обязательной разблокировки/блокировки мутекса библиотеки проста: поскольку суть мутекса состоит в обеспечении взаимного исключения доступа к флагу data_ready, мы хотим запретить потоку-«производителю» изменять флаг data_ready, пока мы его проверяем. Но если мы не разблокируем флаг впоследствии, то поток-«производитель» не сможет его установить, чтобы сообщить нам о доступности данных! Операция повторной блокировки выполняется автоматически исключительно для удобства, чтобы вызвавший функцию pthread_sleepon_wait() поток не беспокоился о состоянии блокировки после «пробуждения».

Давайте перейдем теперь к потоку-«производителю» и рассмотрим, как он использует библиотеку ждущих блокировок. Вот его полная реализация:

>producer() {

> while (1) {

>  // Ждать прерывания от оборудования...

>  pthread_sleepon_lock();

>  data_ready = 1;

>  pthread_sleepon_signal(&data_ready);

>  pthread_sleepon_unlock();

> }

>}

Как вы видите, поток-«производитель» также блокирует мутекс, чтобы получить монопольный доступ к флагу data_ready перед его установкой.

Клиента «пробуждает» не установка флага data_ready в единицу (1), а вызов функции pthread_sleepon_signal()!

Давайте рассмотрим происходящее в подробностях. Определим состояния «потребителя» и «производителя» следующим образом:

СостояниеОзначает
CONDVARожидание соответствующей ждущей блокировке условной переменной
MUTEXожидание мутекса
READYсостояние готовности, т.е., готов выполняться или уже выполняется
INTERRUPTожидание прерывания от аппаратных средств
ДействиеВладелец мутексаСостояние «потребителя»Состояние «производителя»
«потребитель» блокирует мутекс«потребитель»READYINTERRUPT
«потребитель» проверяет флаг data_ready«потребитель»READYINTERRUPT
потребитель вызывает функцию pthread_sleepon_wait()«потребитель»READYINTERRUPT
функция pthread_sleepon_wait() разблокирует мутексмутекс свободенREADYINTERRUPT
функция pthread_sleepon_wait() блокируетсямутекс свободенCONDVARINTERRUPT
пауза до прерываниямутекс свободенCONDVARINTERRUPT
аппаратные средства генерируют данныемутекс свободенCONDVARREADY
«производитель» блокирует мутекс«производитель»CONDVARREADY
«производитель» устанавливает флаг data_ready«производитель»CONDVARREADY
«производитель» вызывает pthread_sleepon_signal()«производитель»CONDVARREADY
«потребитель» «пробуждается», функция pthread_sleepon_wait() пытается заблокировать мутекс«производитель»MUTEXREADY
«производитель» разблокирует мутексмутекс свободенMUTEXREADY
«потребитель» получает мутекс«потребитель»READYREADY
«потребитель» обрабатывает данные«потребитель»READYREADY
«производитель» ждет новых данных от аппаратуры«потребитель»READYINTERRUPT
пауза («потребитель» обрабатывает полученные данные)«потребитель»READYINTERRUPT
«потребитель» завершает обработку и разблокирует мутексмутекс свободенREADYINTERRUPT
«потребитель» возвращается в начало цикла и блокирует мутекс«потребитель»READYINTERRUPT

Последняя строка в таблице повторяет первую — мы совершили один полный цикл.

Каково назначение флага data_ready? Он служит для двух целей:

• Он является флагом состояния — посредником между «потребителем» и «производителем», указывающим на состояние системы. Если флаг установлен в состояние 1, это означает, что данные доступны для обработки; если этот флаг установлено в состояние 0, это означает, что данных нет, и поток-потребитель должен быть заблокирован.

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

• К обсуждению различий между функциями pthread_sleepon_signal() и 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);


Рекомендуем почитать
Это ваше Fido

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


Безопасность информационных систем

В пособии излагаются основные тенденции развития организационного обеспечения безопасности информационных систем, а также подходы к анализу информационной инфраструктуры организационных систем и решению задач обеспечения безопасности компьютерных систем.Для студентов по направлению подготовки 230400 – Информационные системы и технологии (квалификация «бакалавр»).


UNIX — универсальная среда программирования

В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.Для программистов-пользователей операционной системы UNIX.


QNX/UNIX: Анатомия параллелизма

Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса.


Виртуальные  машины: несколько компьютеров в  одном

Применение виртуальных машин дает различным категориям пользователей — от начинающих до IT-специалистов — множество преимуществ. Это и повышенная безопасность работы, и простота развертывания новых платформ, и снижение стоимости владения. И потому не случайно сегодня виртуальные машины переживают второе рождение.В книге рассмотрены три наиболее популярных на сегодняшний день инструмента, предназначенных для создания виртуальных машин и управления ими: Virtual PC 2004 компании Microsoft, VMware Workstation от компании VMware и относительно «свежий» продукт — Parallels Workstation, созданный в компании Parallels.


Недокументированные и малоизвестные возможности Windows XP

Книга содержит подробные сведения о таких недокументированных или малоизвестных возможностях Windows XP, как принципы работы с программами rundll32.exe и regsvr32.exe, написание скриптов сервера сценариев Windows и создание INF-файлов. В ней приведено описание оснасток, изложены принципы работы с консолью управления mmc.exe и параметрами реестра, которые изменяются с ее помощью. Кроме того, рассмотрено большое количество средств, позволяющих выполнить тонкую настройку Windows XP.Эта книга предназначена для опытных пользователей и администраторов, которым интересно узнать о нестандартных возможностях Windows.