Getting return value from a boost::threaded member function?

前端 未结 5 1420
星月不相逢
星月不相逢 2020-12-17 01:19

I have a worker class like the one below:

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

It\'s

相关标签:
5条回答
  • 2020-12-17 01:50

    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.
    
    0 讨论(0)
  • 2020-12-17 01:55

    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
    
    0 讨论(0)
  • 2020-12-17 01:59
    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

    0 讨论(0)
  • 2020-12-17 02:01

    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.

    0 讨论(0)
  • 2020-12-17 02:06

    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

    0 讨论(0)
提交回复
热议问题