8

我有一个像下面这样的工人阶级:

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 的返回值?

提前致谢。

4

5 回答 5

13

另一种选择是使用承诺/期货。

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.
于 2011-11-14T16:41:30.700 回答
7

我认为您无法获得返回值。

相反,您可以将值存储为 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
于 2009-11-11T06:27:36.663 回答
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() 调用的便捷包装器。带参数的线程构造函数

于 2009-11-11T22:35:55.883 回答
1
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”概念,参考此链接

于 2013-07-30T08:16:17.883 回答
-2

另一种选择是使用Boost.Lambda库。然后你可以在不改变类的情况下编写如下代码Worker

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

当您无法更改要调用的函数时,这尤其有用。像这样,返回值被包装在一个局部变量ret中。

于 2010-11-22T16:23:54.983 回答