Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pthread_cond_wait and mutex requirement

Tags:

posix

pthreads

Why it is required to lock a mutex before calling pthread_cond_wait?

Also, is it required to take a lock (on the same mutex) before calling pthread_cond_signal?

thanks for your help.

like image 776
aajtak Avatar asked Jun 10 '11 21:06

aajtak


People also ask

Does pthread_cond_wait need mutex?

The pthread_cond_wait() function blocks the calling thread, waiting for the condition specified by cond to be signaled or broadcast to. When pthread_cond_wait() is called, the calling thread must have mutex locked.

Does pthread_cond_signal lock mutex?

The pthread_cond_signal() routine is used to signal (or wake up) another thread which is waiting on the condition variable. It should be called after mutex is locked, and must unlock mutex in order for pthread_cond_wait() routine to complete.

Does pthread_cond_wait block?

The pthread_cond_wait() and pthread_cond_timedwait() functions are used to block on a condition variable. They are called with mutex locked by the calling thread or undefined behaviour will result.

What does pthread_cond_wait return?

The pthread_cond_wait() routine always returns with the mutex locked and owned by the calling thread, even when returning an error. This function blocks until the condition is signaled. The function atomically releases the associated mutex lock before blocking, and atomically acquires the mutex again before returning.


2 Answers

Why it is required to lock a mutex before calling pthread_cond_wait?

Because otherwise there is an unavoidable race condition.

A mutex protects shared state. A condition variable is associated with some predicate ("condition") on the state. The basic idea is that you want to:

1) check the predicate

2) if the predicate is false, go to sleep until it becomes true

In a concurrent system, it is always possible for some thread to make the predicate true between (1) and (2). To avoid this race, you must hold a mutex before (1) and you must release it atomically as you perform (2).

For example, for a queue the predicate might be "the queue is not empty". But between the time you check to see if the queue is non-empty and the time you go to sleep, some other thread might add something to the queue.

Thus you must hold the mutex both while checking the predicate and at the time you call pthread_cond_wait.

Also, is it required to take a lock (on the same mutex) before calling pthread_cond_signal?

To my knowledge, there is no fundamental problem with this; it just introduces potential inefficiencies.

Here again, whatever shared state you are modifying (and thus making the predicate true) has to be protected by a mutex. So any time you want to signal the condition you must already hold the mutex anyway.

If you release the mutex before signaling the condition, it is possible for the predicate to become false in between due to the action of some other thread. This race does not cause failures because any thread waiting on the condition must double-check the predicate anyway before proceeding... But why put it through the trouble?

Bottom line: Just follow the instructions and you do not even have to think about these questions. :-)

like image 168
Nemo Avatar answered Sep 28 '22 04:09

Nemo


Condition variables are for synchronising on a condition that you are expecting to change. Locking ensures that:

  • The change can be reliably observed on the waiting threads
  • The item under change isn't somehow changed by another thread at the same time one of the now-woken-up threads is observing it

A condition system that doesn't use mutexes would be much more brittle.

like image 21
Chris Jester-Young Avatar answered Sep 28 '22 03:09

Chris Jester-Young