2015-07-18 1 views
0

семафор инициализируется со значением 0.POSIX: значение семафора после выхода из sem_wait()

sem_t sem; 
sem_init(&sem, 0, 0); 

Одна линия исполнения ждет на семафор, а другой один разблокирует его. Во-первых, случай, когда официант должен ждать.

// value is 0 
sem_wait(&sem); // blocks 
            // value is 0 
            sem_post(&sem); 
            // value becomes 1 
// unblocked 

Во-вторых, случай, когда официанту не нужно ждать.

        // value is 0 
            sem_post(&sem); 
            // value becomes 1 

// value is 1 
sem_wait(&sem); // does not block 
// value has become 0 

Проблема заключается в том, что окончательное значение sem отличается в двух случаях: 1 в первом случае и 0 во втором. Это своего рода состояние гонки.

В идеале проблема не возникает, если:

  • , когда значение семафора 0 и sem_wait() называется, значение станет -1, а не оставаться 0. Таким образом, окончательное значение будет должно быть 0 в обоих случаях
  • или существует вариант sem_post(), который просыпался бы один процесс или увеличивать значение (при ожидании процессов значение не будет увеличиваться). также в этом случае конечное значение будет 0 в обоих случаях

Есть ли способ решить это несоответствие в POSIX?

+0

Это не то, как функции должны работать, ['sem_post'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html) увеличивает семафор, а [' sem_wait'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html) уменьшает его? –

ответ

1

Я бы сказал, что ваши последние предположения для 1-го случая ошибочны.

При возврате из заблокированного вызова sem_wait() семафор получает декремент, поэтому он заканчивается значением 0.

man sem_wait() С (Курсив мной):

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

Это выше формулировка отличается от wording used by POSIX, однако это помогает пролить свет на семафор «значение» коррелирует с семафорами запирающих состояния.

+0

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

+1

Когда 'sem_wait()' выходил без декремента семафора, он выходил с ошибкой (а именно, ожидание прерывалось сигналом, возвращаемое значение 'sem_wait()' равно -1 и 'errno' был установлен в' EINTR'). – user377486

+0

Вот почему мы всегда проверяем результат системных вызовов, не так ли?;-) @ user377486 – alk