на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить



Программа 10.3. SynchObj.h: часть 2 — объявления объекта очереди 

/* Объявления структуры обычной ограниченной синхронизированной очереди.*/

/* Очереди закольцованы и реализованы в виде массивов с индексацией */

/* последнего и первого сообщений. */

/* Кроме того, каждая очередь содержит защитный мьютекс и */

/* переменные условий "очередь не пуста" и "очередь не заполнена". */

/* Наконец, имеется указатель массива сообщений произвольного типа. */

typedef struct queue_tag { /* Универсальная очередь. */

 HANDLE q_guard; /* Защита блока сообщения. */

 HANDLE q_ne; /* Очередь не пуста. Вручную сбрасываемое событие. (Автоматически сбрасываемое событие для "сигнальной модели".) */

 HANDLE q_nf; /* Очередь не заполнена. Вручную сбрасываемое событие. (Автоматически сбрасываемое событие для "сигнальной модели".) */

 volatile DWORD q_size; /* Максимальный размер очереди. */

 volatile DWORD q_first; /* Индекс первого сообщения. */

 volatile DWORD q_last; /* Индекс последнего сообщения. */

 volatile DWORD q_destroyed; /* Получатель сообщений очереди завершил выполнение. */

 PVOID msg_array; /* Массив q_size сообщений. */

} queue_t;


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

DWORD q_initialize(queue_t *, DWORD, DWORD);

DWORD q_destroy(queue_t *);

DWORD q_destroyed(queue_t *);

DWORD q_empty(queue_t *);

DWORD q_full(queue_t *);

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.


Объект очереди | Системное программирование в среде Windows | Программа 10.4. QueueObj.с: функции управления очередью