Consider void Futures for One-Shot Event Communication

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.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: