When reading a book on concurrency, the author says a semaphore is different than a condition variable in the way signal() works. The semaphore keeps track of the number of calls to signal() while the condition variable does not. "Calling pthread_cond_signal while no one is waiting has no effect", it says. Why is this detail important (I have seen it repeated many times in different places)? What are the implications to usage? Thank you
-
2See http://stackoverflow.com/questions/3513045/conditional-variable-vs-semaphore for a good explanation of the differences between the two. – goji Dec 11 '12 at 23:48
2 Answers
Conceptually, a semaphore is equivalent to a mutex, condition variable, and integer counter protected by the mutex. Under this analogy, posting a semaphore is equivalent to locking the mutex, incrementing the counter, signaling the condition variable, and unlocking the mutex. Even if there is no waiter, state is still modified.
Under this analogy, waiters for the semaphore are doing the equivalent of:
- Lock mutex.
- While count is non-positive, wait on condition variable.
- Decrement count.
- Unlock mutex.
Of course if you're talking about the specific case of POSIX, the analogy does not correspond fully to the reality, because semaphores have additional async-signal-safety properties that preclude implementing them using a mutex/condvar/count triple.

- 208,859
- 35
- 376
- 711
-
Thank you. When you said pthread semaphore has "async-signal properties", do you mean that if there're 2 threads, one calling signal() and one wait() at the same time, pthread would prevent signal() to be called before wait()? – cody Dec 12 '12 at 00:08
-
No. I mean `sem_post` is specified to be async-signal-safe. This means you can always call it from a signal handler, even in the worst possible case where the same thread was in the middle of `sem_post` or `sem_wait` when the signal interrupted, and it will behave as expected. – R.. GitHub STOP HELPING ICE Dec 12 '12 at 00:42
The implications are that you have to have a 'condition' that the condition variable is associated with. The way you have to use the condition variable is:
acquire the condition's mutex
while (!condition) {
wait on the condition variable
}
do whatever you need to do while holding the mutex
release the mutex
Correspondingly, whenever the condition associated with the condition variable is updated, it has to be done while holding the mutex. That way, when blocking on the condition variable, the condition cannot have changed until the system is prepared to actually unblock the waiting thread.

- 333,147
- 50
- 533
- 760