1

Quoting POSIX:

The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().

"If predictable scheduling behavior is required". This could/would hint that locking the mutex bound to the condition variable right before calling pthread_cond_signal() should guarantee that the signaled thread will be woken up before any other thread manages to lock this mutex. Is this correct?

3 Answers3

1

We will se if any PThreads guru has a more comprehensive answer, but as far as I can see, at least in the Linux manpage, you do not get fully predictable behavior. What you do get is a guarantee that if two threads wait on the same condition variable, the higher-prio thread gets to go first (at least, that should be true on Linux if one thread is SCHED_OTHER and the other is real-time SCHED_FIFO). That holds if you lock mutex before signalling (with reservation for errors after a quick read of the manpage).

See https://linux.die.net/man/3/pthread_cond_signal

Erik Alapää
  • 2,585
  • 1
  • 14
  • 25
  • I recommend the official Linux man-page here: http://man7.org/linux/man-pages/man3/pthread_cond_signal.3p.html – alk Jun 10 '17 at 13:58
  • Tests show that the higher-priority thread always runs first, regardless of whether signal or unlock is done first. Just a comment for people interested in this question. – Yongwei Wu Dec 02 '22 at 08:43
0

No, there is no guarantee the signalled thread will be waken up. Worse, if in the signalling thread you have sequence:

while(run_again) {
    pthread_mutex_lock(&mutex);
    /* prepare data */
    pthread_mutex_unlock(&mutex);
    pthread_cond_broadcast(&cond);
}

there is reasonable chance control would never be passed to other threads waiting on mutex because of logic in the scheduler. Some examples to play with you can find in this answer.

ArturFH
  • 1,697
  • 15
  • 28
0

No.

The best reference I have found regarding the predictability is this one:

https://austin-group-l.opengroup.narkive.com/lKcmfoRI/predictable-scheduling-behavior-in-pthread-cond-broadcast

Basically, people want to guard against the possibility that threads do not get a fair chance to run. Apparently, it is not a problem for most producer-consumer scenarios, and it does not apply to pthread_cond_broadcast as well. I would say, it is useful only in limited cases.

Cppreference.com actually considers unlocking after notifying may be a pessimization:

https://en.cppreference.com/w/cpp/thread/condition_variable/notify_all

Yongwei Wu
  • 5,292
  • 37
  • 49
  • That's a very useful reference. It speaks directly to the question at hand and answers it completely. Unfortunately, *this* answer doesn't summarize the referenced one very well. Or at all, really. – John Bollinger Dec 02 '22 at 22:57
  • @JohnBollinger This answer is not a summary of the link, but an interpretation based on David Butenhof's explanation. If you do not agree, please comment in detail which point contradicts with David's explanation. – Yongwei Wu Dec 03 '22 at 09:20
  • I'm not quite sure what distinction you're drawing between "summarizing" the information and "interpreting" it, particularly since, it already speaks to the exact same question posed here. But interpreting it as "every thread getting a fair chance to run" is largely missing the point. As Butenhof explains, the context for this predictability guarantee is realtime systems and threads with different priorities. The specific predictability that is obtained in this case is that the highest-priority thread wanting to acquire the mutex will reliably acquire it. – John Bollinger Dec 03 '22 at 23:13
  • Reading between the lines a bit, we can take the POSIX provision in question as implying that if a thread that signals a CV does so while holding the associated mutex locked, then the thread that is awakened, if any, will definitely contend for the mutex when the signaling thread eventually unlocks it. There is no possibility of a delay between the signal and the awakened thread starting to contend for the mutex during which some third thread could swoop in and, finding it uncontended, seize the mutex for itself regardless of scheduling policy. – John Bollinger Dec 03 '22 at 23:16
  • That's fair in the sense of helping ensure that the chosen scheduling policy is effective, but it's of most interest in conjunction with scheduling policies that give preferential treatment to some threads over others, which is the opposite of what most people would think of as "fair". – John Bollinger Dec 03 '22 at 23:22
  • @JohnBollinger If an implementation ensures a later mutex locker gets the mutex later too, unlocking later than signalling will help too. This, along with the priority stuff, is what I counted as ‘fair’. – Yongwei Wu Dec 05 '22 at 02:54