Семафор wait() и сигнал()
Я прохожу синхронизацию процессов и сталкиваюсь с трудностями в понимании семафора. Так вот мое сомнение:
источник утверждает, что
" семафор S-это целочисленная переменная, доступ к которой осуществляется через стандартный атомные операции, т. е. wait() и signal ().
Он также предоставил базовое определение wait ()
wait(Semaphore S)
{
while S<=0
; //no operation
S--;
}
определение сигнала()
signal(S)
{
S++;
}
пусть начальное значение семафора равно 1, и скажем, есть два параллельных процесса P0 и P1, которые не должны выполнять операции своего критического раздела одновременно.
Вот скажи Р0 находится в своей критической секции, поэтому семафор s должен иметь значение 0, теперь говорят, что П1 хочет войти в свою критическую секцию, поэтому она выполняет wait () и в wait (), он постоянно петли, теперь для выхода из цикла значение семафора должна быть увеличена, но это может не быть возможным, поскольку по источник, wait (), является атомарная операция и не может быть прерван, и поэтому процесс P0 не может вызвать signal () в одной процессорной системе.
Я хочу знать, является пониманием, я до сих пор правильно или нет. и если правильно, то как происходит процесс P0 call signal (), когда процесс P1 структурирован в цикле while?
5 ответов
Я думаю, что это неточность в свой источник. Atomic
на wait()
операция означает, что каждая ее итерация равна atomic
, что означает S--
выполняется без прерывания, но вся операция прерывается после каждого завершения S--
внутри while
петли.
Я не думаю, что держать бесконечный цикл while внутри операции wait() разумно. Я бы пошел на пример Столлингса;
void semWait(semaphore s){
s.count--;
if(s.count<0)
*place this process in s.queue and block this process
}
когда задача пытается получить семафор, который недоступен, семафор помещает задачу на очередь ожидания и ставит задачу в спящий режим.Процессор может выполнять другой код.Когда семафор становится доступным, одна из задач в очереди ожидания пробуждается, чтобы затем получить семафор.
в то время как S
Я думаю, что книга означает для атомной операции тестирование S<=0
чтобы быть правдой, а также S--
. Прямо как testAndset()
это раньше упомянуть.
если обе отдельные операции S<=0
и S--
являются атомарными, но могут быть прерваны другим процессом, этот метод не будет работать.
представьте себе два процесса p0 и p1, Если p0 хочет войти в критический раздел и протестирован S<=0
чтобы быть правдой. и он был прерван p1 и протестирован S<=0
тоже верно. тогда оба процесс войдет в критический раздел. И это неправильно.
фактическая не атомарная операция находится внутри цикла while, даже если цикл while пуст, другой процесс может прерывать текущий, когда S<=0
протестировано как false, что позволяет другому процессу продолжить свою работу в критическом разделе и отпустить блокировку.
однако, я думаю, что код из книги на самом деле не может использоваться в ОС, так как я не знаю, как делать операции S<=0
чтобы быть правдой, и S--
вместе атомной. более возможный способ сделать это-поставить S--
внутри цикла while, как сказал SomeWittyUsername.
Я думаю, , когда процесс P1 структурирован в цикле while, он будет находиться в состоянии ожидания.процессор переключится между процессом p0 & p1 (переключение контекста), поэтому приоритет переходит на p0, и он вызывает сигнал (), а затем s будет увеличен на 1 и P0 выход из раздела, поэтому процесс P1 может войти в критический раздел и может избежать взаимного исключения