Объекты синхронизации семафоры (semaphores) содержат в себе счетчик текущего числа ресурсов. Семафор находится в свободном состоянии, когда значение его счетчика больше 0. При равенстве счетчика 0, объект переходит в занятое состояние.
Поток получает доступ к ресурсу, вызывая одну из ожидающих функций и передавая ей описатель семафора, который охраняет этот ресурс. Wait-функция проверяет у семафора счетчик текущего числа ресурсов: если его значение больше 0 (семафор свободен), уменьшает значение этого счетчика на 1, и вызывающий поток остается планируемым. Если ожидающая функция определяет, что счетчик текущего числа ресурсов равен 0 (семафор занят), система переводит вызывающий поток в состояние ожидания. Когда другой поток увеличит значение этого счетчика, система возобновит выполнение ждущего потока. Поток же в свою очередь захватит ресурс, уменьшив значение счетчика семафора на 1. Следует отметить, что система не допускает присвоения отрицательных значений счетчику числа ресурсов семафора.
|
|
Объект ядра «семафор» создается вызовом функции CreateSemapbore.
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
Параметр lMaximumCount сообщает системе максимальное допустимое значение счетчика семафора (общее количество ресурсов). Параметр lInitialCount указывает начальное значение счетчика (сколько ресурсов доступно изначально). Значение параметра lInitialCount должно удовлетворять условию 0 ≤ lInitialCount ≤ lMaximumCount. При успешном выполнении функция вернет дескриптор семафора, в противном случае NULL.
Для увеличения значения счетчика текущего числа ресурсов (освобождения ресурсов) используется функция ReleaseSemaphore.
BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);
Данная функция складывает величину lReleaseCount (количество освобождаемых ресурсов) со значением счетчика текущего числа ресурсов. Обычно в параметре lReleaseCount передают 1, но возможно указать и большее значение. Функция возвращает предыдущее значение счетчика ресурсов в lpPreviousCount. Если в программе не требуется это значение, допустима передача значения NULL в качестве значения данного параметра.