Чтение онлайн

на главную - закладки

Жанры

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

Кёртен Роб

Шрифт:

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

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 ожидание прерывания от аппаратных средств
Действие Владелец мутекса Состояние «потребителя» Состояние «производителя»
«потребитель» блокирует мутекс «потребитель» READY INTERRUPT
«потребитель» проверяет флаг data_ready «потребитель» READY INTERRUPT
потребитель вызывает функцию pthread_sleepon_wait «потребитель» READY INTERRUPT
функция pthread_sleepon_wait разблокирует мутекс мутекс свободен READY INTERRUPT
функция pthread_sleepon_wait блокируется мутекс свободен CONDVAR INTERRUPT
пауза до прерывания мутекс свободен CONDVAR INTERRUPT
аппаратные средства генерируют данные мутекс свободен CONDVAR READY
«производитель» блокирует мутекс «производитель» CONDVAR READY
«производитель» устанавливает флаг data_ready «производитель» CONDVAR READY
«производитель» вызывает pthread_sleepon_signal «производитель» CONDVAR READY
«потребитель» «пробуждается», функция pthread_sleepon_wait пытается заблокировать мутекс «производитель» MUTEX READY
«производитель» разблокирует мутекс мутекс свободен MUTEX READY
«потребитель» получает мутекс «потребитель» READY READY
«потребитель» обрабатывает данные «потребитель» READY READY
«производитель» ждет новых данных от аппаратуры «потребитель» READY INTERRUPT
пауза («потребитель» обрабатывает полученные данные) «потребитель» READY INTERRUPT
«потребитель» завершает обработку и разблокирует мутекс мутекс свободен READY INTERRUPT
«потребитель» возвращается в начало цикла и блокирует мутекс «потребитель» READY INTERRUPT

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

Каково назначение флага 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 <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(

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

Последний попаданец 2

Зубов Константин
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50
рейтинг книги
Последний попаданец 2

"Фантастика 2023-123". Компиляция. Книги 1-25

Харников Александр Петрович
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Фантастика 2023-123. Компиляция. Книги 1-25

Мама из другого мира. Дела семейные и не только

Рыжая Ехидна
4. Королевский приют имени графа Тадеуса Оберона
Любовные романы:
любовно-фантастические романы
9.34
рейтинг книги
Мама из другого мира. Дела семейные и не только

Восход. Солнцев. Книга IX

Скабер Артемий
9. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга IX

Идущий в тени 3

Амврелий Марк
3. Идущий в тени
Фантастика:
боевая фантастика
6.36
рейтинг книги
Идущий в тени 3

С Новым Гадом

Юнина Наталья
Любовные романы:
современные любовные романы
эро литература
7.14
рейтинг книги
С Новым Гадом

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Мастер Разума

Кронос Александр
1. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
6.20
рейтинг книги
Мастер Разума

Неожиданный наследник

Яманов Александр
1. Царь Иоанн Кровавый
Приключения:
исторические приключения
5.00
рейтинг книги
Неожиданный наследник

Восход. Солнцев. Книга XI

Скабер Артемий
11. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга XI

Система Возвышения. (цикл 1-8) - Николай Раздоров

Раздоров Николай
Система Возвышения
Фантастика:
боевая фантастика
4.65
рейтинг книги
Система Возвышения. (цикл 1-8) - Николай Раздоров

Таблеточку, Ваше Темнейшество?

Алая Лира
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Таблеточку, Ваше Темнейшество?

Пенсия для морского дьявола

Чиркунов Игорь
1. Первый в касте бездны
Фантастика:
попаданцы
5.29
рейтинг книги
Пенсия для морского дьявола

Герой

Бубела Олег Николаевич
4. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Герой