Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is shared_future<void> a legitimate replacement for a condition_variable?

Josuttis states ["Standard Library", 2nd ed, pg 1003]:

Futures allow you to block until data by another thread is provided or another thread is done. However, a future can pass data from one thread to another only once. In fact, a future's major purpose is to deal with return values or exceptions of threads.

On the other hand, a shared_future<void> can be used by multiple threads, to identify when another thread has done its job.

Also, in general, high-level concurrency features (such as futures) should be preferred to low-level ones (such as condition_variables).

Therefore, I'd like to ask: Is there any situation (requiring synchronization of multiple threads) in which a shared_future<void> won't suffice and a condition_variable is essential?

like image 374
SSteven Avatar asked May 09 '18 08:05

SSteven


People also ask

What is Condition_variable?

The condition_variable class is a synchronization primitive that can be used to block a thread, or multiple threads at the same time, until another thread both modifies a shared variable (the condition), and notifies the condition_variable . The thread that intends to modify the shared variable has to.

What is Pthread_cond_t in C?

DESCRIPTION. 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 is a Condvar?

pub struct Condvar { /* private fields */ } A Condition Variable. Condition variables represent the ability to block a thread such that it consumes no CPU time while waiting for an event to occur. Condition variables are typically associated with a boolean predicate (a condition) and a mutex.

Does condition variable need mutex?

You need condition variables, to be used with a mutex (each cond. var. belongs to a mutex) to signal changing states (conditions) from one thread to another one. The idea is that a thread can wait till some condition becomes true.


2 Answers

As already pointed out in the comments by @T.C. and @hlt, the use of futures/shared_futures is mostly limited in the sense that they can only be used once. So for every communication task you have to have a new future. The pros and cons are nicely explained by Scott Meyers in:

Item 39: Consider void futures for one-shot event communication.
Scott Meyers: Effective Modern C++ (emphasis mine)

His conclusion is that using promise/future pairs dodges many of the problems with the use of condidition_variables, providing a nicer way of communicating one-shot events. The price to pay is that you are using dynamically allocated memory for the shared states and more importantly, that you have to have one promise/future pair for every event that you want to communicate.

like image 134
jotasi Avatar answered Sep 22 '22 17:09

jotasi


While the notion of using high-level abstracts instead of low-level abstract is laudable, there is a misconception here. std::future is not a high-level replacement for std::conditional_variable. Instead, it is a specific high-level construct build for a specific use-case of std::condition_variable - namely, a one-time return of the value.

Obviously, not all uses of condition variable is for this scenario. For example, an message queue can not be implemented with std::future, no matter how much you try. Such a thread is another high-level construct built on low-level building block. So yes, shoot for high-level constructs, but do not expect a one-to-one map mapping between high and low level.

like image 42
SergeyA Avatar answered Sep 22 '22 17:09

SergeyA