Pergunta

Eu tenho uma classe trabalhador como a abaixo:

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

É destinado a ser executado com boost :: fio e boost :: bind, como:

Worker worker;
boost::function<int()> th_func = boost::bind(&Worker::Do, &worker);
boost::thread th(th_func);
th.join();

A minha pergunta é: como faço para obter o valor de retorno do Trabalhador :: Do?

Agradecemos antecipadamente.

Foi útil?

Solução

Eu não acho que você pode obter o valor de retorno.

Em vez disso, você pode armazenar o valor como um membro do Trabalhador:

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

E usá-lo assim:

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

Outras dicas

Outra opção é usar promessas / futuros.

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.

E se você pode usar c ++ 0x, em seguida, usando std :: assíncrono irá empacotar todos os itens acima e apenas fazer:

std::future<int> f = std::async( std::bind(&Worker::Do, &worker) );
int retval = f.get(); //Will block until do returns an int.

Além disso, você também tem algumas ligações redundantes para boost :: bind () e boost :: function (). Você pode, em vez fazer o seguinte:

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));

Você pode fazer isso porque o construtor de linha é um invólucro de conveniência em torno de uma chamada de ligação interna (). Tópico Construtor com argumentos

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();

Você pode dar uma olhada no conceito de "boost :: futuro", ref este link

Outra opção é usar o Boost.Lambda biblioteca. Em seguida, você pode escrever o código da seguinte sem alterar a classe Worker:

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

Isto é útil especialmente quando você não pode alterar a função de chamada. Assim, o valor de retorno é envolto em um ret variável local.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top