Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a condition variable need a lock (and therefore also a mutex) [duplicate]

Condition variables are one of the aspects of c++11 I'm still struggling with a bit. From what I have gathered a condition variable is very similar to a semaphore.

But then again, a semaphore wouldn't need a lock to function. A condition variable does. And a lock in turn needs a mutex. So in order to use the fairly simple functionality of a semaphore we now need to not only manage a condition variable. But also a mutex and a lock.

So why does a condition variable need this? And what added functionality is provided by adding this requirement?

like image 322
laurisvr Avatar asked May 12 '15 14:05

laurisvr


People also ask

Why does condition variable need mutex?

Condition variables are associated with a mutex because it is the only way it can avoid the race that it is designed to avoid.

Why does condition variable need a lock?

If you didn't have a lock associated with the cv then your thread waiting on the cv might wake up then try to (and fail) to acquire the lock associated with the data and therefore have to yield again.

Does condition variable wait unlock mutex?

The pthread_cond_wait() function atomically unlocks mutex and performs the wait for the condition. In this case, atomically means with respect to the mutex and the condition variable and another threads access to those objects through the pthread condition variable interfaces.

What is the conditional variable?

A conditional variable in operating system programming is a special kind of variable that is used to determine if a certain condition has been met or not. It is used to communicate between threads when certain conditions become true. A conditional variable is like a queue.


2 Answers

Condition variables are generally used to signal a change of state. A mutex is usually needed to make that change, and the following signal, atomic.

A semaphore encapsulates some state (a flag or counter) along with the signalling mechanism. A condition variable is more primitive, only providing the signal.

like image 68
Mike Seymour Avatar answered Sep 19 '22 07:09

Mike Seymour


In general once you've signaled something has changed (via a condition variable) you need some code to run to handle that change and that code has to safely read the changed data. If you didn't have a lock associated with the cv then your thread waiting on the cv might wake up then try to (and fail) to acquire the lock associated with the data and therefore have to yield again. With a CV/Lock combo the underlying system can wake your thread up only if the thread can acquire the relevant lock as a unit and so be more efficient.

Its unlikely a CV on its own is useful as it gives no data above the fact it was signaled. If you imagine uses of cv - such as a thread-safe linked list with producers and consumers, you have variables representing {list, cv, lock} . In this case you take the lock, mutate the list, release the lock then signal the cv. On you consumer thread you'll very likely need to take the lock once signaled to act on the list, so having the lock acquired once you wake up from the CV being signaled is a good thing.

Look at something like events on windows (::CreateEvent) which are cv's without the implicit lock, a lot of the time they'll have a lock associated with them, but just not built into the actual usage.

Although this isn't the original reason condition variable in pthreads was created (they used the lock to protect the cv itself which is no longer needed in c++) the reason and usefulness of locks with cv's has migrated to whats in this answer.

like image 22
Mike Vine Avatar answered Sep 18 '22 07:09

Mike Vine