Recently, Scott Meyers, the author of “Effective Modern C++” book gave a webinar presentation titled Consider void Futures for One‑Shot Event Communication, which addressed the issue of how to enable two threads to communicate to each other when a particular task A was completed, but which do not require any shared state.
The solution is to use a RAII (Resource Allocation Is Initialization, Item 37 in the book):
class ThreadRAII {
public:
enum class DtorAction { join, detach };
ThreadRAII(std::thread&& t, DtorAction a)
: action(a), t(std::move(t)) {}
~ThreadRAII()
{
if (t.joinable()) {
if (action == DtorAction::join) t.join();
else t.detach();
}
}
ThreadRAII(ThreadRAII&&) = default; // support
ThreadRAII& operator=(ThreadRAII&&) = default; // moving
std::thread& get() { return t; }
private:
DtorAction action;
std::thread t;
};
and then use it when launching the threads:
{
std::promise<void> p; // created first,
std::thread t2([&p] // destroyed last
{
try {
p.get_future().get();
funcToRun();
}
catch(...) { ... }
});
ThreadRAII tr(std::move(t2), // created after
ThreadRAII::DtorAction::join); // p, destroyed
... // before p
p.set_value();
...
} // if p hasn’t been set, tr’s
// d`tor hangs on a join
There are a few nuances, please see the full deck of slides for the full information.





Leave a comment