9 Stimmen

Rückgabewert einer boost::threaded-Mitgliedsfunktion erhalten?

Ich habe eine Arbeiterklasse wie die folgende:

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

Es ist dafür gedacht, mit boost::thread und boost::bind ausgeführt zu werden, wie:

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

Meine Frage ist, wie bekomme ich den Rückgabewert von Worker::Do?

Vielen Dank im Voraus.

13voto

tgoodhart Punkte 3007

Eine weitere Möglichkeit ist die Verwendung von Versprechen/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.

Und wenn Sie c++0x verwenden können, dann wird die Verwendung von std::async alle oben genannten Punkte zusammenfassen und einfach tun:

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

9voto

Alex Deem Punkte 4607

Ich glaube nicht, dass Sie den Rückgabewert erhalten können.

Stattdessen können Sie den Wert als Mitglied von Worker speichern:

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

Und verwenden Sie es 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

3voto

Imran.Fanaswala Punkte 755

Außerdem haben Sie einige überflüssige Aufrufe von boost::bind() und boost::function(). Sie können stattdessen Folgendes tun:

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

Dies ist möglich, da der Thread-Konstruktor einen internen bind()-Aufruf bequem umschließt. Thread-Konstruktor mit Argumenten

1voto

Marx Yu Punkte 331
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();

Sie können einen Blick auf das "boost::future"-Konzept werfen, z.B. diesen lien

-2voto

Mathias Soeken Punkte 1293

Eine weitere Möglichkeit ist die Verwendung der Boost.Lambda Bibliothek. Dann können Sie den Code wie folgt schreiben, ohne die Worker Klasse:

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

Dies ist insbesondere dann nützlich, wenn Sie die aufzurufende Funktion nicht ändern können. Auf diese Weise wird der Rückgabewert in eine lokale Variable eingeschlossen ret .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X