开发者

pthread_cond_wait and mutex requirement

开发者 https://www.devze.com 2023-03-12 16:49 出处:网络
Why it is required to lock a mutex before calling pthread_cond_wait? Also, is it required t开发者_C百科o take a lock (on the same mutex) before calling pthread_cond_signal?

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

Also, is it required t开发者_C百科o take a lock (on the same mutex) before calling pthread_cond_signal?

thanks for your help.


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


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.


The whole point of condition variables is to allow threads to be notified of changes on data structures protected by a mutex, e.g. you may want to be notified when a queue is no longer empty, so you atomically release the mutex and wait on the condition variable, and when a new element is queued, you are awaken and take the mutex to process the new element.

Unlike Java's monitors, pthread_cond_{signal,broadcast}() doesn't need to hold the mutex. A signalling of a condition variable when no thread is waiting on that condition variable is lost, but that shouldn't make that much of a difference, since the signal could also be lost if the producer starts running before the consumer.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号