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

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

Жанры

Системное программирование в среде Windows

Харт Джонсон М.

Шрифт:

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) {

 if (q_destroyed(q)) return 1;

 /* Освободить все ресурсы, созданные вызовом q_initialize. */

 WaitForSingleObject(q->q_guard, INFINITE);

 q->q_destroyed = 1;

 free(q->msg_array);

 CloseHandle(q->q_ne);

 CloseHandle(q->q_nf);

 ReleaseMutex(q->q_guard);

 CloseHandle(q->q_guard);

 return 0;

}

DWORD q_destroyed(queue_t *q) {

 return (q->q_destroyed);

}

DWORD q_empty(queue_t *q) {

 return (q->q_first == q->q_last);

}

DWORD q_full(queue_t *q) {

 return ((q->q_last – q->q_first) == 1 || (q->q_first == q->q_size-l && q->q_last == 0));

}

DWORD q_remove(queue_t *q, PVOID msg, DWORD msize) {

 char *pm;

 pm = (char *)q->msg_array;

 /* Удалить наиболее давнее ("первое") сообщение. */

 memcpy(msg, pm + (q->q_first * msize), msize);

 q->q_first = ((q->q_first + 1) % q->q_size);

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

}

DWORD q_insert(queue_t *q, PVOID msg, DWORD msize) {

 char *pm;

 pm = (char *)q->msg_array;

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

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

О, мой бомж

Джема
1. Несвятая троица
Любовные романы:
современные любовные романы
5.00
рейтинг книги
О, мой бомж

Возвышение Меркурия. Книга 2

Кронос Александр
2. Меркурий
Фантастика:
фэнтези
5.00
рейтинг книги
Возвышение Меркурия. Книга 2

Вы не прошли собеседование

Олешкевич Надежда
1. Укротить миллионера
Любовные романы:
короткие любовные романы
5.00
рейтинг книги
Вы не прошли собеседование

Метаморфозы Катрин

Ром Полина
Фантастика:
фэнтези
8.26
рейтинг книги
Метаморфозы Катрин

Эволюция мага

Лисина Александра
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эволюция мага

Попаданка для Дракона, или Жена любой ценой

Герр Ольга
Любовные романы:
любовно-фантастические романы
7.17
рейтинг книги
Попаданка для Дракона, или Жена любой ценой

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Сумеречный Стрелок 5

Карелин Сергей Витальевич
5. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 5

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Возвышение Меркурия. Книга 17

Кронос Александр
17. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 17

Переиграть войну! Пенталогия

Рыбаков Артем Олегович
Переиграть войну!
Фантастика:
героическая фантастика
альтернативная история
8.25
рейтинг книги
Переиграть войну! Пенталогия

Волков. Гимназия №6

Пылаев Валерий
1. Волков
Фантастика:
попаданцы
альтернативная история
аниме
7.00
рейтинг книги
Волков. Гимназия №6

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки