Darf man das? boost.Thread + C++0x-Lambdas
-
Ich bin mir mit Threads und Lambdas und ihrem Zusammenspiel noch nicht so 100%ig sicher, daher hier einfach mal die Frage, ob folgendes "erlaubt" (definiertes Verhalten, portabel,...) ist. Es compiliert und läuft und liefert das richtige Ergebnis:
#include <boost/test/unit_test.hpp> #include <boost/thread.hpp> BOOST_AUTO_TEST_CASE(testLambdaThread) { int i = 5; boost::thread incrementer([&](){ i += 2; }); incrementer.join(); BOOST_CHECK(i == 7); }
Wird die capture im anderen Thread richtig rumgereicht und behandelt?
-
Klar, Lambdas sind doch auch nur Funktoren.
-
Ethon schrieb:
Klar, Lambdas sind doch auch nur Funktoren.
"nur" ist gut... ich bin mir halt mit dem ganzen Capture-by-Reference Gedöns nicht so richtig sicher...
-
Ev. hilft dieser Code:
#include <boost/thread.hpp> #include <boost/assert.hpp> struct functor { explicit functor(int& i) : i_(&i) { std::cout << "functor constructed" << std::endl; } functor(const functor& other) : i_(other.i_) { std::cout << "functor copied" << std::endl; } void operator() () { (*i_) += 2; } private: functor& operator==(const functor&); int* i_; }; functor make_functor(int& i) { return functor(i); } int main() { int i = 5; { boost::thread incrementer([&](){ i += 2; }); incrementer.join(); BOOST_ASSERT(i == 7); } { boost::thread incrementer(make_functor(i)); incrementer.join(); BOOST_ASSERT(i == 9); } }
-
theta schrieb:
Ev. hilft dieser Code:
Dass es - falls es richtig läuft - so oder so ähnlich funktionieren muss, ist mir klar. Die Frage war nur, ob es beim Capture-by-Reference irgendeinen Haken gibt im Zusammenhang mit Threads. Aber scheint ja nicht so zu sein
-
Haken gibt es einige. Selbst Herb Sutter (Mister Multithreading persönlich) hat mal auf seinem Blog einen Fehler in dieser Richtung gemacht:
vector<thread> threads; for (int i=0; i<10; ++i) { threads.emplace_back([&]{ ...Teilproblem i loesen... }); } for (auto& t : threads) t.join();
Wo ist der Fehler? --> Datenrennen und Kurzlebigkeit von i. i hätte kopiert werden müssen:
[&,i]{ ...Teilproblem i loesen... }
-
Das Problem hast Du mit Funktoren auch. Es ist prinzipiell ein Problem, wenn man Pointer / Referenzen auf Variablen verwendet, die nicht mehr existieren.
-
Naja, dass die references, die da gecaptured werden, nicht vor dem join danglen dürfen, ist klar