0

In a mediator design pattern with C++, I need to efficiently pass data from one object (running in one thread) to other object running in another thread using bind() call. Assuming I have a mechanism to enqueue function objects into a thread's execution queue (say Thread->Enqueue( functor ))

//Foo's call -- runs in Thread1's context
void Foo::DoSomeWork()
{
    shared_ptr<Object> o = std::make_shared<Object>()
    //fill the object

    //post to mediator
    M.PostData(o);
}

//Thread1 runs functions for class foo. this is called in Thread1's context
void Mediator::PostData(shared_ptr<Object> data)
{
    //Enqueue the functor into Thread2 execution queue 
    Thread2->Enqueue(std::bind(&Bar::ProcessData, Colleague2.get(), data));
}

//Thread2 context
void Bar::ProcessData(shared_ptr<Object> ReceivedData)
{
    //work on ReceivedData object. runs in Thread2's context
    //data passed on to Bar class
} 

instead of copying the shared ptr in the std::bind, is it possible to do std::move(data) to pass on the shared_ptr

e.g. 
Thread2->Enqueue(std::bind(&Bar::ProcessData, Colleague2.get(), std::move(data)));

Not sure if using unique_ptr<> and try moving twice (one in function, other in std::bind will work or help

Pogo
  • 475
  • 3
  • 19
  • Copying a `shared_ptr` isn't all that cheap because of the overhead required to support the sharing. Plus if the pointed-at object isn't shared by multiple [owners](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) `shared_ptr` sends the wrong message. Use `unique_ptr` here. – user4581301 Jan 31 '22 at 17:58
  • Super's now-deleted comment about [using lambda](https://en.cppreference.com/w/cpp/language/lambda) in place of `std::bind` was a good suggestion. – user4581301 Jan 31 '22 at 18:03
  • You can apply `std::move` indeed, also when passing the shared pointer into `PostData` use `std::move`. Here specifically you can use `unique_ptr` unless `Enqueue` requires the callable yo be copyable. Also if you intend to share the ownership between threads then you should use `shared_ptr`. Otherwise `unique_ptr` is preferable for most cases. – ALX23z Jan 31 '22 at 18:11
  • i dont intent to shared ownership across threads, just need to pass on the data from one colleague to other colleague which run in different threads. not sure the overhead of using `std::move` twice for `shared_ptr` or `unique_ptr` if i use either of them. The Enqueue function is basically, `Enqueue( boost::function Functor);` which will enqueue it into a fifo queue for exection by the thread. (thread's queue push/pop operations are thread safe) – Pogo Jan 31 '22 at 18:20
  • `std::move` is a cleaner shortcut for [a moderately complicated cast](https://en.cppreference.com/w/cpp/utility/move). It has, at most, insignificant runtime cost and should optimize away to nothing. – user4581301 Jan 31 '22 at 19:32

0 Answers0