К Т П           План занятия                                                              1                                           Страницы  | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 |

6. Семафоры

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

Создаются семафоры посредством вызова функции CreateSemaphore, которая имеет следующий прототип:
HANDLE CreateSemaphore (
LPSECURITY_ATTRIBUTES lpSemaphoreAttribute,  // атрибуты защиты
LONG UnitialCount,           // начальное значение семафора
LONG IMaximumCount,     // максимальное значение семафора
LPCTSTR lpName              // имя семафора

Пока значение параметра lpsemaphoreAttributes будем устанавливать в null.

Основную смысловую нагрузку в этой функции несут второй и третий параметры. Значение параметра UnitialCount устанавливает начальное значение семафора, которое должно быть не меньше 0 и не больше его максимального значения, которое устанавливается параметром IMaximumCount.

Параметр lpName может указывать на имя семафора или содержать значение null. В последнем случае создается безымянный семафор.

В случае успешного завершения функция CreateSemaphore возвращает дескриптор семафора, в случае неудачи — значение null. Если семафор с заданным именем уже существует, то функция createSemaphor возвращает дескриптор ЭТОГО семафора, а функция GetLastError, вызванная после функции CreateSemaphor, вернет Значение ERROR_ALREADY_EXISTS.

Значение семафора уменьшается на 1 при его использовании в функции ожидания. Увеличить значение семафора можно посредством вызова функции ReleaseSemaphore, которая имеет следующий прототип:
BOOL ReleaseSemaphore (
   HANDLE hSemaphore, // дескриптор семафора
   LONG IReleaseCount, // положительное число. на которое увеличивается значение семафора
   LPLONG IpPreviousCount // предыдущее значение семафора
);

В случае успешного завершения функция ReleaseSemaphore возвращает ненулевое значение, а в случае неудачи — false. Если значение семафора плюс значение параметра iReleaseCount больше максимального значения семафора, то функция ReleaseSemaphore возвращает значение false и значение семафора не изменяется.

Значение параметра ipPreviousCount этой функции может быть равно null. В этом случае предыдущее значение семафора не возвращается.

Доступ к существующему семафору можно открыть с помощью одной из функций CreateSemaphore или OpenSemaphore. Если для этой цели используется функция CreateSemaphore, то значения параметров 1InitialCount и iMaximaiCount этой функции игнорируются, т. к. они уже установлены другим потоком, а поток, вызвавший эту функцию, получает полный доступ к семафору с именем, заданным параметром lpName.

Теперь рассмотрим функцию OpenSemaphore, которая используется в случае, если известно, что семафор с заданным именем уже существует. Эта функция имеет следующий прототип:
HANDLE OpenSemaphore (
   DWORD dwDesiredAccess,   // флаги доступа
   BOOL blnheritHandle,          // режим наследования
   LPCTSTR lpName                // имя события
);

Параметр dwDesiredAccess определяет доступ к семафору и может быть равен любой логической комбинации следующих флагов:
- SEMAPHORE_ALL_ACCESS — полный доступ к семафору;
- SEMAPHORE_MODIFY_STATE — изменение состояния семафора;
- SYNCHRONIZE — синхронизация.

Опишем назначение этих флагов чуть подробнее.
- флаг SEMAPHORE_ALL_ACCESS устанавливает для потока полный доступ к семафору. Это означает, что поток может выполнять над семафором любые действия;
- флаг SEMAPHORE_MODIFY_STATE означает, что поток может использовать только функцию ReleaseSemaphore для изменения значения семафора;
- флаг SYNCHRONIZE означает, что поток может использовать семафор только в функциях ожидания. Отметим, что этот флаг поддерживается только на платформе Windows NT/2000.

 


Предыдущая        В начало страницы       Следующая
6