Объекты синхронизации
(Последний семинар по СПО)
Wait-функция используется для ожидания какого-либо события.
function WaitForSingleObject(
    hHandle: THandle;
    dwMilliseconds: DWORD
): DWORD;
  1. Дескриптор объекта под наблюдением;
  2. Время, в течение которого происходит наблюдение.
Результат функции:
  • WaitObject_0 – объект освободился;
  • Wait_TimeOut – истекло время ожидания;
  • Wait_Failed – ошибка (указан неверный дескриптор).
function WaitForMultipleObjects(
    nCount: DWORD;
    lpHandles: PWOHandleArray;
    bWaitAll: BOOL;
    dwMilliseconds: DWORD
): DWORD;
– ожидание нескольких объектов:
  1. Количество объектов для ожидания;
  2. Указатель на массив дескрипторов объектов;
  3. «булевская» переменная: если TRUE, то ожидание всех объектов; если FALSE, то ожидание освобождения любого;
  4. Время ожидания в миллисекундах.
Возвращает значение типа DWORD. Если происходит ожидание освобождения всех объектов, то результаты аналогичны WaitForSingleObject, если нет, то waitObject_0 означает, что 1-ый объект ядра привёл к прекращению ожидания, waitObject_1 – 2-ой.
События – самый простой объект ядра – содержит счётчик числа пользователей и 2 «булевые» переменные: 1. тип события (с автосбросом или без), 2. начальное состояние события.
Объект «событие» создаётся функцией CreateEvent, которая возвращает дескриптор.
function CreateEvent(
    lpEventAttributes: PSecurityAttributes;
    bManualReset, bInitialState: BOOL;
    lpName: PChar
): THandle;
  1. Указатель на атрибуты безопасности;
  2. Булевая переменная, которая настраивает событие на ручной сброс (TRUE) или на автосброс (FALSE);
  3. Исходное состояние события: TRUE-сигнальное, FALSE-несигнальное;
  4. Имя открытого объекта события (указатель на переменную).
Принцип работы события с автосбросом: если поток успешно дождался сигнала события, то оно автоматически сбрасывается. Т.о. если событие в сигнальном состоянии с автосбросом, то его может дождаться только один поток.
Чтобы перевести событие в свободное или сигнальное состояние, нужно вызвать команду 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;
  1. Указатель на параметры безопасности;
  2. Начальное и максимальное число объектов;
  3. Имя семафора.
Для доступа к семафору из другого процесса используется функция OpenSemaphore. Объекты синхронизации могут быть использованы другим процессом, если:
  1. Он создан из текущего процесса с наследованием;
  2. Используется функция DuplicateHandle;
  3. Используется функция CreateSemaphore с именем уже существующего семафора;
  4. Используется функция OpenSemaphore.
function OpenSemaphore(
    dwDesiredAccess: DWORD;
    bInheritHandle: BOOL;
    lpName: PChar ): THandle;
Работа семафора.
Для получения доступа к ресурсу потоку нужно вызвать Wait-функцию и передать ей дескриптор семафора. Wait-функция проверяет у семафора счётчик числа ресурсов, если он > 0, то его значение уменьшается на единицу. Если счётчик = 0, то поток переходит в состояние ожидания. Как только другой поток освободит семафор и счётчик увеличится на 1, то первый поток «пробуждается» и занимает ресурс. После завершения работы с ресурсом поток должен вызвать функцию ReleaseSemaphore:
function ReleaseSemaphore(
    hSemaphore: THandle;
    lReleaseCount: Longint;
    lpPreviousCount: Pointer
): BOOL;
  1. Дескриптор освобождаемого семафора;
  2. Число, на которое увеличивается текущий счётчик ресурсов;
  3. Переменная для записи начального состояния счётчика.
Объект Мьютекс – обеспечивает взаимоисключающий доступ к одному ресурсу. Мьютекс содержит идентификатор потока, который его захватил. Одним потоком мьютекс может захватываться несколько раз.
Работа Мьютекса: если идентификатор мьютекса = 0, то он свободен, если ≠ 0, то он занят. Создание мьютекса: CreateMutex:
function CreateMutex(
    lpMutexAttributes: PSecurityAttributes;
    bInitialOwner: BOOL;
    lpName: PChar
): THandle;
  1. Указатель на параметры безопасности;
  2. Если FALSE – мьютекс свободен, TRUE - занят создающим потоком;
  3. Имя мьютекса.
Функция возвращает дескриптор мьютекса. Wait-функция проверяет идентификатор мьютекса: 0 – мьютекс свободен, и идентификатору присваивается дескриптор потока, который его захватывает; не равен 0 – мьютекс занят и поток переходит в состояние ожидания.
Освобождение мьютекса: ReleaseMutex с одним параметром – дескриптором освобождаемого потока.
function ReleaseMutex (hMutex: THandle): BOOL;
Для работы с критическими секциями используется InitialiseCriticalSection(имя критической секции). Код критической секции начинается с вхождения в критическую секцию EnterCriticalSection(имя), а заканчивается LeaveCriticalSection(имя). Для работы с критической секцией не нужны Wait-функции. EnterCriticalSection проверяет занятость критической секции. TryEnterCriticalSection – попытка зайти в критическую секцию, при отказе поток не завершается, а выполняется дальше.


Ctrl  Предыдущая  •  Следующая  Ctrl
Сайт управляется системой uCoz