Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС СФМЭИ.doc
Скачиваний:
22
Добавлен:
17.09.2019
Размер:
1.37 Mб
Скачать

7.2.7. События

События уведомляют об окончании какой-либо операции. Объекты-события бывают двух типов: со сбросом вручную (manual-reset events) и с автосбросом (auto-reset events). Первые позволяют возобновлять выполнение сразу нескольких ждущих потоков, вторые — только одного.

Объекты-события обычно используют в том случае, когда какой-то поток выполняет инициализацию, а затем сигнализирует другому потоку, что тот может продолжить работу. Инициализирующий поток переводит объект «событие» в занятое состояние и приступает к своим операциям. Закончив, он сбрасывает событие в свободное состояние. Тогда другой поток, который ждал перехода события в свободное состояние, пробуждается и вновь становится планируемым.

Для работы с объектом «событие» используются следующие функции:

1. Создание объекта ядра «событие», функция CreateEvent:

function CreateEvent(lpEventAttributes: PSecurityAttributes;

bManualReset, bInitialState: Boolean; lpName: PChar): THandle;

где lpEventAttributes - указывает на структуру SECURITY_ATTRIBUTES, которая содержит информацию о защите объекта ядра «событие». Если защиты не нужно в этот параметр заносится nil.

Пареметр fManualReset (булева переменная) определяет тип объекта «событие» - событие со сбросом вручную (TRUE) или с автосбросом (FALSE).

Параметру fInitialState определяет начальное состояние события — свободное (TRUE) или занятое (FALSE).

lpName – указатель на строку, заканчивающуюся двоичным нулем и содержащую имя объекта «событие». Применяется в тех случаях, когда объект «событие» используется для синхронизации потоков разных процессов. Если объект «событие» используется для синхронизации потоков одного процесса, этот параметр устанавливается в nil.

После того как система создает объект событие, CreateEvent возвращает дескриптор события, специфичный для конкретного процесса. Потоки из других процессов могут получить доступ к этому объекту:

  • вызовом CreateEvent с тем же параметром lpName;

  • наследованием дескриптора;

  • применением функции DuplicateHandle;

  • вызовом OpenEvent c передачей в параметре lpName имени, совпадающего с указанным в аналогичном параметре функции CreateEvent.

2. Открытие объекта ядра «событие», функция OpenEvent:

function OpenEvent(dwDesiredAccess: DWORD; bInheritHandle: Boolean;

lpName: PChar): THandle;

где dwDesiredAccess - определяет требуемый доступ к объекту «событие». Возможные значения данного параметра приведены в таблице 7.3.

bInheritHandle - определяет тип наследования данного дескриптора. Если данный параметр имеет значение TRUE, процесс, создаваемый функцией CreateProcess, будет наследовать данный дескриптор. Если же данный параметр имеет значение FALSE, дескриптор события не будет наследуемым.

lpName – указатель на сроку, заканчивающуюся двоичным нулем и содержащую имя объекта «событие».

Таблица 7.3 Значения параметра dwDesiredAccess

Параметр dwDesiredAccess

Описание

EVENT_ALL_ACCESS

Означает все возможные флаги доступа для объекта «событие»

EVENT_MODIFY_STATE

Объект событие можно использовать только в функциях SetEvent и ResetEvent для изменения состояния объекта «событие»

SYNCHRONIZE

Допускается использование объекта «событие» в любой wait- функции для ожидания освобождения события.

  1. Закрытие объекта ядра «событие».

Ненужный объект ядра «событие» следует закрыть вызовом CloseHandle.

4. Перевод события в свободное состояние

function SetEvent(hEvent: THandle): Boolean;

где hEvent – дескриптор события. При успешном выполнении функция возвращает ненулевое значение. В случае ошибки функция возвращает ноль.

5. Перевод события в занятое состояние

function ResetEvent(hEvent: THandle): Boolean;

где hEvent – дескриптор события.

При успешном выполнении функция возвращает ненулевое значение. В случае ошибки функция возвращает ноль.

Для событий с автосбросом действует следующее правило. Когда его ожидание потоком успешно завершается, этот объект автоматически сбрасывается в занятое состояние. Отсюда и произошло название таких объектов-событий. Для этого объекта обычно не требуется вызывать ResetEvent, поскольку система сама восстанавливает его состояние.