Семафор 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 может войти в критический раздел и может избежать взаимного исключения