Семафор является счетчиком, и вы можете вызывать две функции для него: decrement
(также известный как wait
, p
и т. Д.) И increment
(post
, signal
, v
и т. д.).
Когда поток вызывает wait
на семафоре, происходит следующее:
- Если счетчик семафоров больше 0, счетчик уменьшается на 1 и вызов
wait
возвращает
- Если число семафоров меньше или равно 0, вызов
wait
будет ожидать увеличения числа семафоров до 1 или более (что произойдет, когда другие потоки вызовут post
на семафоре), вычтите 1 из числа и вернуть
Цикл while
в приведенном выше коде предназначен для обработки второго случая. Функция не должна возвращаться до тех пор, пока счетчик не станет больше 0 (именно поэтому условие цикла равно S <= 0
), поэтому цикл while будет продолжать вращаться до тех пор, пока этот счетчик не станет больше 0. Цель цикла while состоит исключительно в остановке функция от продвижения. Нет тела кода, который вы хотите выполнить повторно.
Оператор if
недостаточен для обработки этого случая, потому что он просто проверяет S <= 0
один раз. Функция может опережать оператор if
, даже если число все еще меньше или равно 0.
Обратите внимание, что код семафора в вашем учебнике является большим упрощением того, как работают настоящие семафоры. Как правило, если поток вызывает wait
, а число меньше или равно 0, поток выдаст результат, и планировщик переведет его в спящий режим, пока другой поток не вызовет post
. Таким образом, либо цикл while либо отсутствует, либо любой цикл while будет немного отличаться от того, который указан в вашем вопросе. Кроме того, в семафорной структуре должен быть какой-то механизм защиты целочисленного счетчика. В противном случае, несколько потоков могут стремиться увеличить / уменьшить этот счетчик, и несколько потоков могут продвинуться дальше цикла while, даже если счетчик изначально равен 1 (поэтому семафор не будет правильно защищать критическую секцию).