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

7.2.6. Семафоры

Объекты ядра «семафор» используются для учета ресурсов Как и все объекты ядра, они содержат счетчик числа пользователей, но, кроме того, поддерживают два 32 битных значения со знаком: одно определяет максимальное число ресурсов (контролируемое семафором), другое используется как счетчик текущего числа ресурсов

Для семафоров определены следующие правила:

  • когда счетчик текущего числа ресурсов становится больше 0, семафор переходит в свободное состояние,

  • если этот счетчик равен 0, семафор занят,

  • система не допускает присвоения отрицательных значений счетчику текущего числа ресурсов;

  • счетчик текущего числа ресурсов не может быть больше максимального числа ресурсов

Не следует путать счетчик текущего числа ресурсов со счетчиком числа пользователей объекта-семафора

Объект ядра «семафор» создается вызовом функции CreateSemapbore: function CreateSemaphore(lpSemaphoreAttributes: PSecurityAttributes;

lInitialCount, lMaximumCount: Longint; lpName: PChar): THandle;

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

lInitialCount – счетчик текущего числа ресурсов.

lMaximumCount – максимальное число ресурсов, контролируемое семафором. Данный параметр должен быть больше 0.

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

При успешном выполнении функции CreateSemaphore возвращает дескриптор семафора, В случае ошибки функция возвращает nil. Причем, если при вызове функции CreateSemaphore указывается имя семафора и объект «семафор» с таким именем уже существует, то функция вернет значение – nil, а функция GetLastError вернет значение - ERROR_ALREADY_EXISTS.

Любой процесс может получить свой («процессно-зависимый») дескриптор существующего объекта «семафор», вызвав функцию OpenSemaphore:

function OpenSemaphore(dwDesiredAccess: DWORD; bInheritHandle: Boolean;

lpName: PChar): THandle;

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

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

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

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

Значение

Описание

SEMAPHORE_ALL_ACCESS

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

SEMAPHORE _MODIFY_STATE

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

SYNCHRONIZE

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

Поток получает доступ к ресурсу, вызывая одну из Wait-функций и передавая ей дескриптор семафора. Wait-функция проверяет у семафора счетчик текущего числа ресурсов, если его значение больше 0 (семафор свободен), уменьшает значение этого счетчика на 1, и вызывающий поток остается планируемым

Если Wait-функция определяет, что счетчик текущего числа ресурсов равен 0 (семафор занят), система переводит вызывающий поток в состояние ожидания. Когда другой поток увеличит значение этого счетчика, система вспомнит о ждущем потоке и снова начнет выделять ему процессорное время (а он, захватив ресурс, уменьшит значение счетчика на 1).

Поток увеличивает значение счетчика текущего числа ресурсов, вызывая функцию ReleaseSemaphore:

function ReleaseSemaphore(hSemaphore: THandle; lReleaseCount:

Longint; lpPreviousCount: Pointer): Boolean;

Где hSemaphore – дескриптор семафора.

Данная функция складывает величину lReleaseCount со значением счетчика текущего числа ресурсов. Обычно в параметре lReleaseCount передают 1, но это вовсе не обязательно. Функция возвращает исходное значение счетчика ресурсов в lpPreviousCount. Если исходное значение счетчика в приложении не используется, то вместо параметра lpPreviousCount записывается значение nil.

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