This is a general question. For example, currently two child threads have called pthread_cond_wait(&cond1,&mutex)
, and they are both waiting. Then, the parent thread calls
pthread_cond_signal(&cond1);
pthread_cond_signal(&cond1);
Next, my question is, is it guaranteed that both of the two waiting threads will get woken up?(Suppose the first thread woken up releases mutex later at certain stage of execution so that the second thread can acquire it).
The reason for me to ask this question is because, for the Unix system level signal, the signal (say SIGCHLD
) is not queued so that multiple signal of same type may be lost if they are delivered consecutively. So I wonder is pthread_cond_signal
implemented differently so that they will not get lost if the scheduler happen to let the parent thread signal twice in a row?
I know this is an old thread (no pun intended), but a typical implementations works like this:
A condition variable will have within it a queue of threads which are currently asleep, waiting for it to get signalled.
A lock will have a queue of threads which have been put to sleep because they attempted to acquire it but it was held by another thread.
cond_wait adds the running thread to the condition variable's queue, releases the lock, and puts itself to sleep.
cond_signal simply moves one sleeping thread from the queue of the condition variable to the queue of the lock.
When the running thread releases the lock, a sleeping thread is removed from the lock's queue, ownership of the lock is transferred to that sleeping thread, and that sleeping thread is woken up.
Don't ask my why the spec says that a cond_signal might wake up more than one thread...
The quick answer:
pthread_cond_signal()
will wake up at least one of the threads that is blocked on the condition variable - but more than that is not guaranteed (for reference, usepthread_cond_broadcast()
to wake up all blocked threads).From here:
The longer answer:
So, according to the specification, I'd presume the unblocking to happen synchronously, that is, a thread that has been unblocked by the first call to
pthread_cond_signal()
will be seen as unblocked by the second call topthread_cond_signal()
, and thus the other thread will be waken up.However, I do not know whether this is the case for your specific pthread implementation or not (and the glibc website is pretty dodgy at the moment, so can't get access to code to look at).
The probably-not-yet-implemented-but-it-is-in-the-specification answer:
It should be noted though, that the specification recently got slightly reworded regarding how the
pthread_cond_signal()
andpthread_cond_broadcast()
determine which threads are actually blocked on a given condition variable, but I presume that not all implementations have caught up yet.A long discussion on the subject can be found here, with the new specification being:
So, the conclusion: Without being an expert interpreter of specifications, I'd say that the new text supports the assumption of this happening synchronously - so that two consecutive calls to
pthread_cond_signal()
with two blocked threads available, will wake up both threads.I'm not 100% sure on this though, so if anyone can elaborate, feel free to do so.