Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СППО .doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
190.46 Кб
Скачать

Семафор создается функцией

function CreateSemaphore (

Attr: Pointer; // указатель на атрибуты безопасности

InitialCount: longint; // Начальное число потоков, // допущенных к объекту

MaxCount: longint; // Максимальное число допускаемых // потоков

lpName: PChar // имя семафора

): THandle; // дескриптор семафора

Семафор сигнализирует, если InitialCount больше нуля, и не подает сигнала, если InitialCount равен нулю.

Для доступа к объекту используется функция ожидания WaitForSingleObject или WaitForMultipleObjects.

При завершении функции ожидания значение счетчика InitialCount соответственно уменьшается, и поток получает доступ к ресурсу.

При завершении доступа к ресурсу необходимо вызвать функцию, увеличивающую значение счетчика семафора:

function ReleaseSemaphore(

hHandle: THandle; // дескриптор мьютекса

ReleaseCount: longint // приращение счетчика

LP: Pointer // как правило, nil

): Boolean;

4.4. События (Event)

Данные объекты синхронизации используются обычно не для доступа к данным, а для того, чтобы оповестить другие потоки о том, что некоторое действие завершено. Пусть, например, в некотором приложении один поток читает данные из файла в буфер памяти, а другие потоки их обрабатывают. В начале работы первый поток устанавливает объект «Cобытие» в несигнальное состояние. Остальные потоки выполнили вызов функции ожидания и находятся в приостановленном состоянии, ожидая наступления события. Как только буфер заполняется, первый поток сообщает об этом ОС, вызывая сигнализацию события, ОС активизирует потоки.

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

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

function CreateEvent( lpEventAttributes: PSecurityAttributes; //адрес //структуры атрибутов безопасности bManualReset, //определяет, будет ли событие отключаемым //вручную (TRUE) или автоматически (FALSE) bInitialState: BOOL; // задает начальное состояние (если // TRUE то событие сигнализирует) lpName: PChar // имя или NIL, если имя не требуется ):Thandle; stdcall; // возвращает дескриптор события

Параметр lpName позволяет разделять объекты между процессами. Как и в случае с мьютексами, если lpName совпадает с именем уже существующего объекта типа Event, созданного текущим или любым другим процессом, функция не создает нового объекта, а возвращает идентификатор уже существующего. При этом игнорируются параметры bManualReset, bInitialState и lpSecurityDescriptor.

Если объект используется для синхронизации внутри одного процесса, его можно объявить как глобальную переменную и создавать без имени. Имя объекта не должно совпадать с именем любого из существующих объектов синхронизации.

Если известно, что Event уже создан, для получения доступа к нему можно вместо CreateEvent воспользоваться функцией:

function OpenEvent( dwDesiredAccess: DWORD; // Задает права доступа к объекту bInheritHandle: BOOL; // Задает, может ли объект // наследоваться дочерними процессами lpName: PChar // Имя объекта ): THandle; stdcall;

Функция возвращает дескриптор (идентификатор объекта), либо 0, в случае ошибки. Параметр dwDesiredAccess может принимать одно из следующих значений:

EVENT_ALL_ACCESS

Приложение получает полный доступ к объекту

EVENT_MODIFY_STATE

Приложение может изменять состояние объекта функциями SetEvent и ResetEvent

SYNCHRONIZE

Только для Windows NT/2k/XP – приложение может использовать объект только в функциях ожидания

После получения идентификатора можно приступать к его использованию. Функция

function SetEvent(hEvent: THandle): BOOL; stdcall;

устанавливает объект в сигнальное состояние.

Функция

function ResetEvent(hEvent: THandle): BOOL; stdcall;

сбрасывает объект, устанавливая его в несигнальное состояние.

Функция

function PulseEvent(hEvent: THandle): BOOL; stdcall

устанавливает объект в сигнальное состояние, дает отработать всем функциям ожидания, ожидающим этот объект, а затем снова сбрасывает его.

По завершении работы с объектом, он должен быть уничтожен функцией CloseHandle. Примеры использования событий приведены в статье [3].