Getting return value from a boost::threaded member function?
I hav开发者_开发问答e a worker class like the one below:
class Worker{
public:
int Do(){
int ret = 100;
// do stuff
return ret;
}
}
It's intended to be executed with boost::thread and boost::bind, like:
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.
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 package up 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.
I don't think you can get the return value.
Instead, you can store the value as a member of Worker:
class Worker{
public:
void Do(){
int ret = 100;
// do stuff
m_ReturnValue = ret;
}
int m_ReturnValue;
}
And use it like so:
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
In addition, you also have some redundant calls to boost::bind() and boost::function(). You can instead 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 Thread's constructor is a convenience wrapper around an internal bind() call. Thread Constructor with arguments
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 "boost::future" concept, ref this link
Another option is using the Boost.Lambda library. Then you can 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 in particular when you cannot change the function to call. Like this, the return value is wrapped in a local variable ret
.
精彩评论