3
votes

When a thread waits on a condition variable, the associated mutex is (atomically) released (unlocked). When that condition variable is signaled (by a different thread), one (for signal) or all (for broadcast) waiting thread(s) is/are awakened, automatically re-acquiring (locking) the mutex.

What will happen if one or more other threads are waiting to acquire (lock) that same mutex, but not waiting on the same condition? Are the thread(s) waiting on the condition variable guaranteed to be awakened (and thus acquire the mutex) before the mutex can be acquired (locked) by the other threads, or could the other thread(s) acquire (lock) the mutex before the thread(s) waiting on the condition variable?

[Note: the example below is simplified for clarity. Thread_B does not really start Thread_C, but Thread_C is guaranteed to not be running until after Thread_B has acquired the mutex - it does not compete with Thread_B for the mutex after Thread_A waits on the condition variable]

Thread_A:

pthread_mutex_lock(&myMutex);
while (!someState) {
    pthread_cond_wait(&myCondVar,&myMutex);
}
// do something
pthread_mutex_unlock(&myMutex);

Thread_B:

pthread_mutex_lock(&myMutex);
// do other things
someState = true;
// start Thread_C here
pthread_cond_signal(&myCondVar);
pthread_mutex_unlock(&myMutex);

Thread_C:

pthread_mutex_lock(&myMutex);
// can I reach this point after Thread_B releases the mutex,
// but before Thread_A re-acquires it after being signaled?

// do things that may interfere with Thread_A...
pthread_mutex_unlock(&myMutex);

Edit: The accepted answer below was chosen because it makes clear that whether or not a reader agrees with the interpretation given, there is enough ambiguity that the only safe assumption to make is that of the respondent. Note that others well-versed in C++-standard-speak may find the text totally unambiguous... I am not in that group.

1
What will happen if one or more other threads are waiting to acquire (lock) that same mutex, but not waiting on the same condition? - it's the same as two threads waiting for the same mutex. Note that from docs The effect of using more than one mutex for concurrent ... pthread_cond_wait() operations on the same condition variable is undefined;KamilCuk
@Kamil Cuk note that I am using the same mutex for pthread_cond_wait() as I am to protect pthread_cond_signal(). Only one mutex and one condVar in play.ags
Why do you have to use the same mutex for two purposes? Do you have to pay for each mutex objects? Logically mutex and it's condition variable are married to each other, and there is no reason to use one without the other.SergeyA
@SergeyA I agree. Using one mutex is simpler (and possibly reduces chance of deadlock... but that's also an issue of poor design/implementation). If I cannot confirm that signaled threads are not competing for the mutex with other (non-signaled) threads, I will use a different, unique mutex as you suggest.ags

1 Answers

3
votes

There's nothing special about acquiring a mutex when awakened from pthread_cond_[timed]wait() compared to any other thread already blocked in pthread_mutex_lock() trying to acquire the same mutex.

Per the POSIX 7 pthread_cond_signal() documentation (bolding mine):

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

Acquiring the mutex after waking up from pthread_cond_[timed]wait() is required to be exactly as if the thread had called pthread_mutex_lock().

In short, any of the threads can acquire the mutex.