从 boost::threaded 成员函数中获取返回值?
Posted
技术标签:
【中文标题】从 boost::threaded 成员函数中获取返回值?【英文标题】:Getting return value from a boost::threaded member function? 【发布时间】:2010-12-15 08:26:20 【问题描述】:我有一个像下面这样的工人阶级:
class Worker
public:
int Do()
int ret = 100;
// do stuff
return ret;
它打算与 boost::thread 和 boost::bind 一起执行,例如:
Worker worker;
boost::function<int()> th_func = boost::bind(&Worker::Do, &worker);
boost::thread th(th_func);
th.join();
我的问题是,如何获得 Worker::Do 的返回值?
提前致谢。
【问题讨论】:
【参考方案1】:另一种选择是使用承诺/期货。
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.
如果你可以使用 c++0x,那么使用 std::async 将打包以上所有内容并执行以下操作:
std::future<int> f = std::async( std::bind(&Worker::Do, &worker) );
int retval = f.get(); //Will block until do returns an int.
【讨论】:
【参考方案2】:我不认为你可以得到返回值。
相反,您可以将值存储为 Worker 的成员:
class Worker
public:
void Do()
int ret = 100;
// do stuff
m_ReturnValue = ret;
int m_ReturnValue;
然后像这样使用它:
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
【讨论】:
谢谢,我想我必须重新设计一下。【参考方案3】:此外,您还有一些对 boost::bind() 和 boost::function() 的冗余调用。您可以改为执行以下操作:
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));
您可以这样做,因为 Thread 的构造函数是内部 bind() 调用的便捷包装器。 Thread Constructor with arguments
【讨论】:
这看起来很简单。谢谢,但我的实际实现包含许多成员函数,所以我不能真正使用 () 运算符。 @何世明:不用bind()还是可以用的。例如, boost::thread(worker(),&Worker::Do) (语法可能略有偏差,因为它是我的头顶)。【参考方案4】: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();
你可以看看“boost::future”的概念,参考这个link
【讨论】:
【参考方案5】:另一个选择是使用Boost.Lambda 库。然后可以在不改变Worker
类的情况下编写如下代码:
Worker worker;
int ret;
boost::thread th( boost::lambda::var( ret ) = worker.Do() );
th.join();
当您无法更改要调用的函数时,这尤其有用。像这样,返回值被包裹在一个局部变量ret
中。
【讨论】:
这将在当前线程中执行worker.Do()
,将结果复制到一个lambda对象中,在新线程上运行该lambda(从而将worker.Do()
的结果分配给ret
),然后然后等待新线程的执行完成。这很可能不是期望的行为,因为它在错误的线程中执行worker.Do()
。从在不同线程中执行的函数返回结果的最简单正确方法是使用期货和承诺。以上是关于从 boost::threaded 成员函数中获取返回值?的主要内容,如果未能解决你的问题,请参考以下文章