Читаем Системное программирование в среде Windows полностью

DWORD q_get(queue_t *, PVOID, DWORD, DWORD);

DWORD q_put(queue_t *, PVOID, DWORD, DWORD);

DWORD q_remove(queue_t *, PVOID, DWORD);

DWORD q_insert(queue_t *, PVOID, DWORD); 

В программе 10.4 представлены такие функции, как q_initialize и q_get, прототипы которых описаны в конце программы 10.3. Обратите внимание, что функции q_get и q_put обеспечивают синхронизацию доступа, а функции q_remove и q_insert, которые вызываются первыми двумя функциями, сами по себе не являются синхронизированными и могут быть использованы в однонитевых программах. В первых двух функциях предусмотрена возможность использования конечных интервалов ожидания, что требует незначительного расширения модели переменных условий.

q_empty и q_full — две другие важные функции, которые используются для реализации предикатов переменных условий.

Данная реализация использует функцию PulseEvent и вручную сбрасываемые события (широковещательная модель), так что все события уведомляются о том, что очередь не пуста или не заполнена.

Замечательной особенностью этой реализации является симметрия функций q_get и q_put. Обратите внимание хотя бы на то, как в этих функциях используются предикаты пустой и заполненной очередей или события. Подобная простота не только восхитительна сама по себе, но и имеет благоприятные практические последствия, облегчающие написание, понимание и сопровождение программы, и все это было достигнуто за счет использования модели переменных условий. 

Наконец, те, кто программирует на C++, легко сообразят, что приведенный код может быть использован для создания класса синхронизированной очереди; именно это вам и предлагается сделать в упражнении 10.8.

Программа 10.4. QueueObj.с: функции управления очередью 

/* Глава 10. QueueObj.c. */

/* Функции очереди */

#include "EvryThng.h"

#include "SynchObj.h"

/* Функции управления конечной ограниченной очередью. */

DWORD q_get(queue_t *q, PVOID msg, DWORD msize, DWORD MaxWait) {

 if (q_destroyed (q)) return 1;

 WaitForSingleObject(q->q_guard, INFINITE);

 while (q_empty(q)) {

  SignalObjectAndWait(q->q_guard, q->q_ne, INFINITE, FALSE);

  WaitForSingleObject(q->q_guard, INFINITE);

 }

 /* Удалить сообщение из очереди. */

 q_remove(q, msg, msize);

 /* Сигнализировать о том, что очередь не заполнена, поскольку мы удалили сообщение. */

 PulseEvent(q->q_nf);

 ReleaseMutex(q->q_guard);

 return 0;

}

DWORD q_put(queue_t *q, PVOID msg, DWORD msize, DWORD MaxWait) {

 if (q_destroyed(q)) return 1;

 WaitForSingleObject(q->q_guard, INFINITE);

 while(q_full(q)) {

  SignalObjectAndWait(q->q_guard, q->q_nf, INFINITE, FALSE);

  WaitForSingleObject(q->q_guard, INFINITE);

 }

 /* Поместить сообщение в очередь. */

 q_insert(q, msg, msize);

 /* Сигнализировать о том, что очередь не пуста; мы вставили сообщение.*/

 PulseEvent (q->q_ne);

 /* Широковещательная модель CV. */

 ReleaseMutex(q->q_guard);

 return 0;

}

DWORD q_initialize(queue_t *q, DWORD msize, DWORD nmsgs) {

 /* Инициализация очереди, включая ее мьютекс и события. */

 /* Выделить память для всех сообщений. */

 q->q_first = q->q_last = 0;

 q->q_size = nmsgs;

 q->q_destroyed = 0;

 q->q_guard = CreateMutex(NULL, FALSE, NULL); 

 q->q_ne = CreateEvent(NULL, TRUE, FALSE, NULL);

 q->q_nf = CreateEvent(NULL, TRUE, FALSE, NULL);

 if ((q->msg_array = calloc(nmsgs, msize)) == NULL) return 1;

 return 0; /* Ошибки отсутствуют. */

}

DWORD q_destroy(queue_t *q) {

Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT