Getting return value from boost :: threaded member?

I have a working class like below:

class Worker{ public: int Do(){ int ret = 100; // do stuff return ret; } } 

It is designed to run with boost :: thread and boost :: bind, for example:

 Worker worker; boost::function<int()> th_func = boost::bind(&Worker::Do, &worker); boost::thread th(th_func); th.join(); 

My question is: how do I get the return value of Worker :: Do?

Thanks in advance.

+6
c ++ boost boost-bind boost-thread boost-function
source share
5 answers

I do not think you can get the return value.

Instead, you can save the value as a member of the Work item:

 class Worker{ public: void Do(){ int ret = 100; // do stuff m_ReturnValue = ret; } int m_ReturnValue; } 

And use it like this:

 Worker worker; boost::function<void()> th_func = boost::bind(&Worker::Do, &worker); boost::thread th(th_func); th.join(); //do something with worker.m_ReturnValue 
+7
source share

Another option is to use promises / futures.

 class Worker{ public: void Do( boost::promise<int> & p){ int ret = 100; // do stuff p.set_value(ret); } }; //Later... boost::promise<int> p; boost::thread t( boost::bind(&Worker::Do, &worker, boost::ref(p)); int retval = p.get_future().get(); //This will block until the promise is set. 

And if you can use C ++ 0x, then using std :: async will pack all of the above and just do:

 std::future<int> f = std::async( std::bind(&Worker::Do, &worker) ); int retval = f.get(); //Will block until do returns an int. 
+13
source share

In addition, you also have redundant calls to boost :: bind () and boost :: function (). Instead, you can do the following:

 class Worker{ public: void operator(){ int ret = 100; // do stuff m_ReturnValue = ret; } int m_ReturnValue; } Worker worker; boost::thread th(worker());//or boost::thread th(boost::ref(worker)); 

You can do this because the Thread constructor is a convenient wrapper around the bind () internal call. Stream constructor with arguments

+2
source share
 class Worker{ public: int Do(){ int ret = 100; // do stuff return ret; } } Worker worker; boost::packaged_task<int> ptask(boost::bind(&Worker::Do, &worker)); boost::unique_future<int> future_int = ptask.get_future(); boost::thread th(boost::move(ptask)); th.join(); if (future_int.is_ready()) int return_value = future_int.get(); 

You can take a look at the concept of "boost :: future" link

+1
source share

Another option is to use the Boost.Lambda library. You can then write the code as follows without changing the Worker class:

 Worker worker; int ret; boost::thread th( boost::lambda::var( ret ) = worker.Do() ); th.join(); 

This is useful, especially if you cannot change the function to call. Like this, the return value is wrapped in the local variable ret .

-2
source share

All Articles