Using std::promise
s 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::promise
s 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
wait
on itsstd::future<void>
orstd::shared_future<void>
- The communications channel wil permit the reacting task to know when the detecting task has
written
itsvoid
data by callingset_value
on 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_future
produced bystd::future::share()
↩︎