Программирование для Windows NT

       

Как работает семафор


В отличие от железнодорожного семафора, который может быть либо открыт, разрашая движение, либо закрыт, запрещая его, семаформы в операционной системе Microsoft Windows NT действуют более сложным образом.

Так же как и объект Mutex, семафор может находиться в отмеченном или неотмеченном состоянии. Приложение выполняет ожидание для семафора при помощи таких функций, как WaitForSingleObject или WaitForMultipleObject (точно также, как и для объекта Mutex). Если семафор находится в неотмеченном состоянии, задача, вызвавшая для него функцию WaitForSingleObject, находится в состоянии ожидания. Когда же состояние семафора становится отмеченным, работа задачи возобновляется. В такой логике работы для вас, однако, нет ничего нового.

В отличие от объекта Mutex, с каждым семафором связывается счетчик, начальное и максимальные значения которого задаются при создании семафора. Значение этого счетчика уменьшается, когда задача вызывает для семафора функцию WaitForSingleObject или WaitForMultipleObject, и увеличивается при вызове другой, специально предназначенной для этого функции.

Если значение счетчика семафора равно нулю, он находится в неотмеченном состоянии. Если же это значение больше нуля, семафор переходит в отмеченное состояние.

Пусть, например, приложение создало семафор, указав для него максимальное значение счетчика, равное трем. Пусть начальное значение этого счетчика также будет равно трем.

Если в этой ситуации несколько запускаемых по очереди задач будут выполнять с помощью функции WaitForSingleObject ожидание семафора, то первые три запущенные задачи будут работать, а все остальные перейдут в состояние ожидания. Это связано с тем, что первые три вызова функции WaitForSingleObject приведут к последовательному уменьшению значения счетчика семафора до нуля, в результате чего семафор переключится в неотмеченное состояние.

Задача, запущенная четвертой, вызовет функцию WaitForSingleObject для неотмеченного семафора, в результате чего она будет ждать. Точно также, задачи, запущенные после запуска четвертой задачи, будут выполнять ожидание для того же семафора.


Как долго продлится ожидание?

До тех пор, пока одна из первых трех задач не освободит семафор, увеличив его счетчик на единицу вызовом специальной функции. Сразу после этого будет запущена одна из задач, ожидающих наш семафор.

На рис. 4.4 мы показали последовательное изменение счетчика семафора (обозначенного символом N) при запуске первых трех задач. Так как счетчик больше нуля, семафор открыт, то есть находится в отмеченном состоянии и поэтому функция WaitForSingleObject не будет выполнять ожидание.



Рис. 4.4. Изменение значения счетчика семафора от трех до единицы

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



Рис. 4.5. После запуска четвертой задачи семафор закрывается


Содержание раздела