Using std::promises and futures is useful skill to create one-shot communication between a detecting task and reacting task.
Sometimes we want a task to detect some event and then inform a second asynchronously running task to proceed when some event has taken place (e.g., a data structure has been initialized, a stage of computation has been completed, a significant sensor value has been detected, etc.). In other words, a detecting task will detect a special event/condition, and a reacting task will wait until the detecting task notifies that the event occurs/condition changes.
If we only want to inform once, we can take use of the power of std::promises and futures (i.e., std::future and std::shared_future). Since both std::promise and futures are templates requiring a type parameter that indicates the type of data to be transmitted through the communications channel, we specify this type as void indicating that no data is to be conveyed:
- The detecting task will set its
std::promise<void>when the event of interest occurs - The reacting task will
waiton itsstd::future<void>orstd::shared_future<void> - The communications channel wil permit the reacting task to know when the detecting task has
writtenitsvoiddata by callingset_valueon itsstd::promise
The essence of the technique looks like,
|
|
Taking use of std::future::share()1, a general form is easy to implement where originally one reacting task extent to many:
|
|
-
std::future::share()transfers ownership of its shared state to thestd::shared_futureproduced bystd::future::share()↩︎