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 future
s) should be preferred to low-level ones (such as condition_variable
s).
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?
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.
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.
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.
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.
As already pointed out in the comments by @T.C. and @hlt, the use of future
s/shared_future
s 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_variable
s, 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With