Is it guaranteed that pthread_cond_signal will wak

2019-01-27 15:02发布

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?

2条回答
smile是对你的礼貌
2楼-- · 2019-01-27 15:10

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...

查看更多
劫难
3楼-- · 2019-01-27 15:25

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, use pthread_cond_broadcast() to wake up all blocked threads).

From here:

The pthread_cond_signal() call unblocks at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

The pthread_cond_broadcast() call unblocks all threads currently blocked on the specified condition variable cond.

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 to pthread_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() and pthread_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:

The pthread_cond_broadcast() and pthread_cond_signal() functions shall atomically determine which threads, if any, are blocked on the specified condition variable cond. This determination shall occur at an unspecified time during the pthread_cond_broadcast() or pthread_cond_signal() call. The pthread_cond_broadcast() function shall then unblock all of these threads. The pthread_cond_signal() function shall unblock at least one of these threads.

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.

查看更多
登录 后发表回答