Получение возвращаемого значения из функции-члена boost::threaded?

StackOverflow https://stackoverflow.com/questions/1713171

Вопрос

У меня есть рабочий класс, подобный приведенному ниже:

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?

Заранее спасибо.

Это было полезно?

Решение

Я не думаю, что вы сможете получить возвращаемое значение.

Вместо этого вы можете сохранить значение как член 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

Другие советы

Другой вариант — использовать обещания/фьючерсы.

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.

Кроме того, у вас также есть несколько избыточных вызовов 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 представляет собой удобную оболочку внутреннего вызова метода связывания(). Конструктор потоков с аргументами

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», см. это связь

Другой вариант — использовать Boost.Лямбда библиотека.Затем вы можете написать код следующим образом, не меняя Worker сорт:

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

Это особенно полезно, когда вы не можете изменить вызываемую функцию.Таким образом, возвращаемое значение заворачивается в локальную переменную. ret.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top