1
votes

This question is regarding the pthread tutorial in llnl. Say there are three threads.

Thread 1:

pthread_mutex_lock(&mutex)
do_something...
if condition
    pthread_cond_signal(&con)
pthread_mutex_unlock(&mutex)
repeat

Thread 2:

pthread_mutex_lock(&mutex)
do_something...
if condition
    pthread_cond_signal(&con)
pthread_mutex_unlock(&mutex)
repeat

Thread 3:

pthread_mutex_lock(&mutex)
while(condition not holds)
    pthread_cond_wait(&con)
    do_something...
pthread_mutex_unlock(&mutex)

Assume that Thread1 checks that condition is satisfied and then sends signal to wake up Thread3. Finally it unlocks the mutex. But at the same time, Thread 2 is trying to lock the mutex.

My question is: is there any guarantee that Thread3 will always win in the competition?

If not then after Thread2 do_something..., the condition variable may be changed, then when Thread3 gets to lock the mutex, the condition variable is different from what it expects.

2
There is no such guarantee. If at all it happened 10 out of 10 times, it's still purely out of luck. - Arunmu
There is no such guarantee. This is precisely why you need the while loop around pthread_cond_wait! And you shouldn't have do_something... inside that while loop for the same reason. - user253751

2 Answers

4
votes

My question is: is there any guarantee that Tread3 will always win in the competition?

No such guarantees. From POSIX:

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

If more than one thread is blocked on a condition variable, the scheduling policy shall determine the order in which threads are unblocked. When each thread unblocked as a result of a pthread_cond_broadcast() or pthread_cond_signal() returns from its call to pthread_cond_wait() or pthread_cond_timedwait(), the thread shall own the mutex with which it called pthread_cond_wait() or pthread_cond_timedwait(). The thread(s) that are unblocked shall contend for the mutex according to the scheduling policy (if applicable), and as if each had called pthread_mutex_lock().

(Emphasis mine).

If not then after Tread2 do_something..., the condition variable may be changed, then when Tread3 gets to lock the mutex, the condition variable is different from what it expects.

If the order of execution of threads matter then you probably need to rewrite your code.

0
votes

There is no guarantee. Returning from pthread_cond_wait() should be treated as implying that the condition might have changed, not that it definitely has - so you need to re-check the condition, and may need to wait again. This is exactly why pthread_cond_wait() should be called within a loop that checks the condition.