mercredi 29 septembre 2021

Most efficient way to pass arguments (inclduing std::function) to costructor in multithreaded environment

The multithreaded program is similar to the following:

struct Timer {
   Timer (boost::asio::io_service& ios) : timer_{ios} {}
   boost::asio::steady_timer timer_;
};

struct TimerContext {
   void                *ctxt_{nullptr};
   void                *cookie_{nullptr};
   TimerEventCallback   teCallback_{nullptr};
};

class A {
   std::function<void(Timer *, const TimerContext&)>    callback_;
   int                                                  id_;
   std::string                                          name_;
   boost::asio::io_service                              ios_;
   std::thread                                          thread_;
};

A's constructor:

A::A (std::function<void(Timer *, const TimerContext&)> cb, int id, std::string name) :
   callback_{cb},
   id_{id},
   name_{name}
{
   thread_ = std::thread{[this] () {
         // some code
      }
   };
}

The callback function definition (free function as of now, written by me):

void
customCallback (Timer *timer, const TimerContext& ctxt) {
   log << __func__ << "timer id: " << (void *)timer;

   auto ret = ctxt.teCallback_(timer, ctxt.cookie_);

   log << __func__ << ret;
}

In main(),

for (int i = 0; i < 5; ++i) {
   int id = getId(i);
   std::string name = getName(i);

   A *a = new A{customCallback, id, name};

   vectorA.push_back(a);

}

I can think of two approaches:

  1. Pass constructor arguments by value and then std::move them in the constructor initializer list.
A *a = new A{customCallback, id, name};

A::A (std::function<void(Timer *, const TimerContext&)> cb, int id, std::string name) :
   callback_{std::move(cb)},
   id_{std::move(id)},
   name_{std::move(name)}
  1. Pass constructor arguments by const reference and then and allow the copy to occur in the constructor initializer list.
A *a = new A{customCallback, id, name};

A::A (const std::function<void(Timer *, const TimerContext&)> &cb, const int &id, const std::string &name) :
   callback_{cb},
   id_{id},
   name_{name}

Which one would be more efficient in terms of copy and performance? If there is a better approach (till and including c++14), please suggest.

Aucun commentaire:

Enregistrer un commentaire