从 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 成员函数中获取返回值?的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使从类内部获取成员函数指针值也需要类名限定?

在 Python 中获取单成员集合中的唯一元素

从 Dll 调用具有偏移地址的成员函数

MFC,是不是有任何方便的方法可以在其成员函数中获取编辑框的内容?

如何从静态成员函数调用指向成员函数的指针?

C++中怎么获取类的成员函数的函数指针