Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform - [28]
> 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().
Основное различие здесь состоит в том, что библиотека ждущих блокировок имеет скрытый внутренний мутекс, а при использовании условных переменных мутекс передается явно. Последний способ дает нам больше гибкости.
И, наконец, обратите внимание на то, что мы использовали функцию pthread_cond_signal() вместо функции pthread_sleepon_signal() (опять же, с явной передачей мутекса).
В разделе о ждущих блокировках мы обещали обсудить различие между функциями pthread_sleepon_broadcast() и pthread_sleepon_signal(). Заодно поговорим и о различии между двумя аналогичными функциями, имеющими отношение к условным переменным: pthread_cond_signal() и pthread_cond_broadcast().
В двух словах, функция в варианте «signal» разблокирует только один поток. Например, если бы несколько потоков находилось в ожидании по функции «wait», и некий поток вызвал бы функцию pthread*_signal(), то был бы разблокирован только один из ждущих потоков. Который из них? Тот, у которого наивысший приоритет. Если имеется два или более потоков с одинаковым приоритетом, порядок «пробуждения» будет не определен. Применение же варианта pthread*_broadcast() приведет к тому что будут разблокированы все ожидающие потоки.
Разблокировать все потоки может показаться излишним. Но с другой стороны, разблокировать только один (причем случайный поток тоже не совсем корректно.
Поэтому мы должны думать, где имеет смысл использовать какой вариант. Очевидно, что если у вас только один ждущий поток, как у нас и было во всех вариантах «потребителя», функция pthread*_signal() прекрасно справится — будет разблокирован один поток, и как раз тот, который нужно (потому что других просто нет).
В ситуации с несколькими потоками в первую очередь следует выяснить: а почему они ждут? Обычно на этот вопрос есть два ответа:
• все потоки рассматриваются как эквивалентные и реально образуют пул доступных потоков, готовых к обработке некоторого запроса;
• все потоки являются уникальными, и каждый из них ждет соблюдения своего специфического условия.
В первом случае мы можем представить себе, что код всех потоков имеет примерно следующий вид:
>/*
> * cv1.c
>*/
>#include
>#include
>pthread_mutex_t mutex_data = PTHREAD_MUTEX_INITIALIZER;
>pthread_cond_t cv_data = PTHREAD_COND_INITIALIZER;
>int data;
>thread1() {
> for (;;) {
> pthread_mutex_lock(&mutex_data);
> while (data == 0) {
> pthread_cond_wait(&cv_data, &mutex_data);
> }
> // Сделать что-нибудь
> pthread_mutex_unlock(&mutex_data);
> }
>}
В этом случае абсолютно неважно, который именно из потоков получит данные — главное, чтобы хотя бы один сделал это и произвел над этими данными необходимые действия.
Однако, если ваш код подобен приведенному ниже, все будет несколько по-иному:
>/*
> * cv2.c
>*/
>#include
>#include
>pthread_mutex_t mutex_xy = PTHREAD_MUTEX_INITIALIZER;
>pthread_cond_t cv_xy = PTHREAD_COND_INITIALIZER;
>int x, y;
>int isprime(int);
>thread1() {
> for (;;) {
> pthread_mutex_lock(&mutex_xy);
> while ((x > 7) && (y != 15)) {
> pthread_cond_wait(&cv_xy, &mutex_xy);
> }
> // Сделать что-нибудь
> pthread_mutex_unlock(&mutex_xy);
> }
>}
>thread2() {
> for (;;) {
> pthread_mutex_lock(&mutex_xy);
> while (!isprime(x)) {
> pthread_cond_wait(&cv_xy, &mutex_xy);
> }
> // Сделать что-нибудь
> pthread_mutex_unlock(&smutex_xy);
> }
>}
>thread3() {
> for (;;) {
> pthread_mutex_lock(&mutex_xy);
> while (x != y) {
![Виртуальные машины: несколько компьютеров в одном](/storage/book-covers/d3/d3d21efc0138d31faad0917369f9053e064085e5.jpg)
Применение виртуальных машин дает различным категориям пользователей — от начинающих до IT-специалистов — множество преимуществ. Это и повышенная безопасность работы, и простота развертывания новых платформ, и снижение стоимости владения. И потому не случайно сегодня виртуальные машины переживают второе рождение.В книге рассмотрены три наиболее популярных на сегодняшний день инструмента, предназначенных для создания виртуальных машин и управления ими: Virtual PC 2004 компании Microsoft, VMware Workstation от компании VMware и относительно «свежий» продукт — Parallels Workstation, созданный в компании Parallels.
![Недокументированные и малоизвестные возможности Windows XP](/storage/book-covers/3c/3c1be627c1d69a562e3fca9dc54a9a80bbae29e0.jpg)
Книга содержит подробные сведения о таких недокументированных или малоизвестных возможностях Windows XP, как принципы работы с программами rundll32.exe и regsvr32.exe, написание скриптов сервера сценариев Windows и создание INF-файлов. В ней приведено описание оснасток, изложены принципы работы с консолью управления mmc.exe и параметрами реестра, которые изменяются с ее помощью. Кроме того, рассмотрено большое количество средств, позволяющих выполнить тонкую настройку Windows XP.Эта книга предназначена для опытных пользователей и администраторов, которым интересно узнать о нестандартных возможностях Windows.
![Windows Vista. Мультимедийный курс](/storage/book-covers/90/9076fd7cf40e08475c322090e7c5bab39a1bf5f1.jpg)
Эта книга поможет вам разобраться в премудростях операционной системы Windows Vista.Информационная насыщенность учебного материала позволяет утверждать, что мультимедийный курс будет интересен и новичкам, и опытным пользователям.
![FAQ по смартфону Qtek 8300/8310](/storage/book-covers/02/029347a6079e3c00093e55140234dcb20c9c97fa.jpg)
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
![Домашние и офисные сети под Vista и XP](/storage/book-covers/60/60ea92e91fc065c1a8fc203657d970b52abd1821.jpg)
Количество персональных компьютеров в нашей стране растет год от года. Сегодня во многих семьях имеется два или даже три компьютера.Чтобы воспользоваться всеми преимуществами такой ситуации, компьютеры в вашей квартире стоит объединить сетью. Это позволит вам играть по сети в компьютерные игры, совместно использовать дисковое пространство, принтеры, модемы и другие устройства, всю сеть можно соединить с Интернетом. А в офисах сеть между компьютерами просто необходима.Открывающиеся перспективы выглядят очень заманчиво.
![Свободные программы и системы в школе](/build/oblozhka.dc6e36b8.jpg)
Курс лекций, включенных в брошюру, знакомит читателя с популярными свободными программами и системами, полезными при преподавании информатики в средней школе. В обзор вошли основы открытых операционных систем, сведения о пакете «офисных» программ OpenOffice.org, коммуникационном пакете Mozilla, графическом редакторе GIMP, современных графических средах GNOME и KDE и других программах.Для преподавателей информатики и методистов, а также для студентов и аспирантов соответствующих специальностей.© 2002-3, Максим Отставнов.© 2002, Андрей Добровольский (раздел 3.1).Использован текст лекций, публиковавшихся автором в приложении к газете «Первое сентября» «Информатика» (http://inf.1september.ru) в 2002-3 г., материалы брошюры «Прикладные свободные программы в школе» (М.: 2003 г.), а также фрагменты статей, ранее публиковавшихся в журналах «Компьютерра» и «Домашний компьютер».Материалы, представленные в этой книге, также доступны в Интернет на странице www.otstavnov.com/fsft на условиях Свободной лицензии ГНУ на документацию (GNU FDL)