Объекты синхронизации (Последний семинар по СПО) |
Wait-функция используется для ожидания какого-либо события.
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD ): DWORD;
Результат функции:
nCount: DWORD; lpHandles: PWOHandleArray; bWaitAll: BOOL; dwMilliseconds: DWORD ): DWORD; – ожидание нескольких объектов:
Возвращает значение типа DWORD. Если происходит ожидание освобождения всех объектов, то результаты аналогичны WaitForSingleObject, если нет, то waitObject_0 означает, что 1-ый объект ядра привёл к прекращению ожидания, waitObject_1 – 2-ой.
События – самый простой объект ядра – содержит счётчик числа пользователей и 2 «булевые» переменные: 1. тип события (с автосбросом или без), 2. начальное состояние события.
Объект «событие» создаётся функцией CreateEvent, которая возвращает дескриптор.
function CreateEvent(lpEventAttributes: PSecurityAttributes; bManualReset, bInitialState: BOOL; lpName: PChar ): THandle;
Принцип работы события с автосбросом: если поток успешно дождался сигнала события, то оно автоматически сбрасывается. Т.о. если событие в сигнальном состоянии с автосбросом, то его может дождаться только один поток.
Чтобы перевести событие в свободное или сигнальное состояние, нужно вызвать команду SetEvent, чтобы сбросить (занятое) – ResetEvent. Чтобы открыть событие из другого процесса нужно вызвать функцию управления OpenEvent.
function SetEvent(hEvent: THandle): BOOL;function ResetEvent(hEvent: THandle): BOOL; function OpenEvent( dwDesiredAccess: DWORD; bInheritHandle: BOOL; lpName: PChar ): THandle; Семафоры – используются для ограничения доступа нескольких объектов к ресурсам. Содержит счётчик числа пользователей, максимальное число контролируемых ресурсов (32 б), счётчик текущего числа ресурсов (используемых – 32 б). В Windows семафор работает следующим образом: если счётчик числа ресурсов > 0 – семафор свободен; если равен 0 – семафор занят. Счётчик текущего числа ресурсов < сч.контролируемых ресурсов.
Создаётся функцией CreateSemaphore, которая возвращает дескриптор семафора.
function CreateSemaphore(lpSemaphoreAttributes: PSecurityAttributes; lInitialCount, lMaximumCount: Longint; lpName: PChar ): THandle;
Для доступа к семафору из другого процесса используется функция OpenSemaphore. Объекты синхронизации могут быть использованы другим процессом, если:
dwDesiredAccess: DWORD; bInheritHandle: BOOL; lpName: PChar ): THandle; Работа семафора.
Для получения доступа к ресурсу потоку нужно вызвать Wait-функцию и передать ей дескриптор семафора. Wait-функция проверяет у семафора счётчик числа ресурсов, если он > 0, то его значение уменьшается на единицу. Если счётчик = 0, то поток переходит в состояние ожидания. Как только другой поток освободит семафор и счётчик увеличится на 1, то первый поток «пробуждается» и занимает ресурс. После завершения работы с ресурсом поток должен вызвать функцию ReleaseSemaphore:
function ReleaseSemaphore(hSemaphore: THandle; lReleaseCount: Longint; lpPreviousCount: Pointer ): BOOL;
Объект Мьютекс – обеспечивает взаимоисключающий доступ к одному ресурсу. Мьютекс содержит идентификатор потока, который его захватил. Одним потоком мьютекс может захватываться несколько раз.
Работа Мьютекса: если идентификатор мьютекса = 0, то он свободен, если ≠ 0, то он занят. Создание мьютекса: CreateMutex:
function CreateMutex(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PChar ): THandle;
Функция возвращает дескриптор мьютекса. Wait-функция проверяет идентификатор мьютекса: 0 – мьютекс свободен, и идентификатору присваивается дескриптор потока, который его захватывает; не равен 0 – мьютекс занят и поток переходит в состояние ожидания.
Освобождение мьютекса: ReleaseMutex с одним параметром – дескриптором освобождаемого потока.
function ReleaseMutex (hMutex: THandle): BOOL;
Для работы с критическими секциями используется InitialiseCriticalSection(имя критической секции). Код критической секции начинается с вхождения в критическую секцию EnterCriticalSection(имя), а заканчивается LeaveCriticalSection(имя). Для работы с критической секцией не нужны Wait-функции. EnterCriticalSection проверяет занятость критической секции. TryEnterCriticalSection – попытка зайти в критическую секцию, при отказе поток не завершается, а выполняется дальше.
|