[boost] Thread-Klasse
-
Hi, vor einigen Jahren habe ich C++ in der Berufsschule kennengelernt
(auch, wenn wir da mehr mit C-Konstrukten gearbeitet haben, aber was soll's).
In den letzten 2 1/2 Jahren habe ich durch's Studium intensiv mit Java und
privat viel mit Python gearbeitet. Inzwischen will ich mich wieder an C++
"ranwagen" - bisher problemlos.Allerdings komme ich beim Thema Multithreading nicht weiter. Von Java kenne
ich die Thread-Klasse und habe eine solche in C++ gesucht. Nach einer Weile
Googeln bin ich nun beim boost-Framework hängengeblieben. Allerdings klappt
es nicht so recht, eine Thread-Klasse - wie ich sie aus Java kenne -
nachzubauen. Erstmal hier der Code meiner parallel.cpp:#include <iostream> #include <boost/thread.hpp> #include <boost/bind.hpp> using namespace std; // meine Thread-Klasse class Thread { private: boost::thread* thread; public: Thread() { // hier versuche ich die run-Methode als Thread zu starten this->thread = new boost::thread(boost::bind(&Thread::run, this)); } ~Thread() { this->thread->join(); } virtual void run() {} }; // und das ist dann meine von Thread abgeleitete Klasse class MyThread: public Thread { public: virtual void run() { // ... mit irgendwelchen Anweisungen cout << "foobar" << endl; } }; int main() { MyThread* mt = new MyThread(); delete mt; // damit der thread irgendwann "gejoint" wird und das Programm beenden kann return 0; }
Kompiliere ich (btw verwende ich unter Linux Ubuntu den g++ als Compiler)
meinen Code, erhalte ich einen Haufen (aus meiner Sicht) undefinierbarer
Fehlermeldungen:/tmp/ccyQmUsE.o: In function
boost::detail::thread\_data\_base::thread\_data\_base()': parallel.cpp:(.text.\_ZN5boost6detail16thread\_data\_baseC2Ev[\_ZN5boost6detail16thread\_data\_baseC5Ev]+0x1a): undefined reference to
vtable for boost::detail::thread_data_base'
/tmp/ccyQmUsE.o: In functionThread::~Thread()': parallel.cpp:(.text.\_ZN6ThreadD2Ev[\_ZN6ThreadD5Ev]+0x19): undefined reference to
boost::thread::join()'
/tmp/ccyQmUsE.o: In functionboost::thread::thread<boost::\_bi::bind\_t<void, boost::\_mfi::mf0<void, Thread>, boost::\_bi::list1<boost::\_bi::value<Thread*> > > >(boost::\_bi::bind\_t<void, boost::\_mfi::mf0<void, Thread>, boost::\_bi::list1<boost::\_bi::value<Thread*> > >, boost::disable\_if<boost::is\_convertible<boost::\_bi::bind\_t<void, boost::\_mfi::mf0<void, Thread>, boost::\_bi::list1<boost::\_bi::value<Thread*> > >&, boost::detail::thread\_move\_t<boost::\_bi::bind\_t<void, boost::\_mfi::mf0<void, Thread>, boost::\_bi::list1<boost::\_bi::value<Thread*> > > > >, boost::thread::dummy*>::type)': parallel.cpp:(.text.\_ZN5boost6threadC2INS\_3\_bi6bind\_tIvNS\_4\_mfi3mf0Iv6ThreadEENS2\_5list1INS2\_5valueIPS6\_EEEEEEEET\_NS\_10disable\_ifINS\_14is\_convertibleIRSE\_NS\_6detail13thread\_move\_tISE\_EEEEPNS0\_5dummyEE4typeE[\_ZN5boost6threadC5INS\_3\_bi6bind\_tIvNS\_4\_mfi3mf0Iv6ThreadEENS2\_5list1INS2\_5valueIPS6\_EEEEEEEET\_NS\_10disable\_ifINS\_14is\_convertibleIRSE\_NS\_6detail13thread\_move\_tISE\_EEEEPNS0\_5dummyEE4typeE]+0x31): undefined reference to
boost::thread::start_thread()'
/tmp/ccyQmUsE.o: In functionboost::detail::thread\_data<boost::\_bi::bind\_t<void, boost::\_mfi::mf0<void, Thread>, boost::\_bi::list1<boost::\_bi::value<Thread*> > > >::~thread_data()': parallel.cpp:(.text.\_ZN5boost6detail11thread\_dataINS\_3\_bi6bind\_tIvNS\_4\_mfi3mf0Iv6ThreadEENS2\_5list1INS2\_5valueIPS6\_EEEEEEED2Ev[\_ZN5boost6detail11thread\_dataINS\_3\_bi6bind\_tIvNS\_4\_mfi3mf0Iv6ThreadEENS2\_5list1INS2\_5valueIPS6\_EEEEEEED5Ev]+0x16): undefined reference to
boost::detail::thread_data_base::~thread_data_base()'
/tmp/ccyQmUsE.o:(.rodata._ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv6ThreadEENS2_5list1INS2_5valueIPS6_EEEEEEEE[typeinfo for boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, Thread>, boost::_bi::list1<boost::_bi::value<Thread*> > > >]+0x8): undefined reference to `typeinfo for boost::detail::thread_data_base'
collect2: ld gab 1 als Ende-Status zurückIch hoffe, dass jemand eine Idee hat, was ich falsch mache
LG Glocke
-
Du musst noch die libboost_thread dazu linken. Und wenn du das gemacht hast, auch noch den Compilerschalter -pthread (sowohl beim Linken als auch beim Compilieren).
Aber wenn du mit dem g++ unter Linux unterwegs bist, dann nimm doch gleich die Threads aus der C++11-Standardbibliothek. Die sind ziemlich genau das gleiche wie die Boost-Threads + Futures&Promises, aber ohne dass du eine Abhängigkeit von Boost hast.
-
Glocke schrieb:
Allerdings klappt es nicht so recht, eine Thread-Klasse - wie ich sie aus Java kenne - nachzubauen.
Warum solltest du das tun wollen?
Das ist wie wenn du daher kommst und sagst "ich kenne Autos schon aus England. Jetzt nehme ich ein Auto aus Deutschland und versuche die englischen Autos nachzubauen. Ich hab schon ein Lenkrad auf die andere Seite montiert und das andere abgebaut. Aber so richtig tut das noch nicht..."
C++ ist nicht Java. Versuch also auch nicht, in C++ irgendwas nachzubauen, was du aus Java kennst. Vor allem dann nicht, wenn es in C++ schon was fertiges gibt.
-
Ich hab jetzt mal das Example von http://en.cppreference.com/w/cpp/thread/thread/thread genommen
#include <iostream> #include <utility> #include <thread> #include <chrono> #include <functional> #include <atomic> void f1(int n) { for(int i=0; i<5; ++i) { std::cout << "Thread " << n << " executing\n"; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void f2(int& n) { for(int i=0; i<5; ++i) { std::cout << "Thread 2 executing\n"; ++n; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } int main() { int n = 0; std::thread t1; // t1 is not a thread std::thread t2(f1, n+1); // pass by value std::thread t3(f2, std::ref(n)); // pass by reference std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread t2.join(); t4.join(); std::cout << "Final value of n is " << n << '\n'; }
und es probiert mit g++ test.cpp -o test -std=c++0x compiliert. Beim Ausführen kommt
terminate called after throwing an instance of 'std::system_error' what(): Operation not permitted Abgebrochen (Speicherabzug geschrieben)
Was hab ich diesmal veregssen?
@pumuckl: Es gibt schon so eine Klasse? Warum finde ich die nicht
-
SeppJ schrieb:
[...] Und wenn du das gemacht hast, auch noch den Compilerschalter -pthread (sowohl beim Linken als auch beim Compilieren).
[...]
-
Kein Kommentar xDD Danke
-
Glocke schrieb:
Ich hab jetzt mal das Example von http://en.cppreference.com/w/cpp/thread/thread/thread genommen
[...]
@pumuckl: Es gibt schon so eine Klasse? Warum finde ich die nichtDies ist alles sehr verwirrend...
-
Glocke schrieb:
@pumuckl: Es gibt schon so eine Klasse? Warum finde ich die nicht
Jup, die nennt sich std::thread... warum du nicht findest, was du die ganze Zeit schon benutzt, versteh ich auch nicht
-
Mal abgesehen davon, dass die Java-Threads so ziemlich der groesste Design-Fail ueberhaupt sind. Pfui Teufel.
-
Kellerautomat schrieb:
Mal abgesehen davon, dass die Java-Threads so ziemlich der groesste Design-Fail ueberhaupt sind. Pfui Teufel.
Na wenn der mächtige Kellerautomat das sagt muss es ja wohl stimmen einself.
-
class Thread implements Runnable
-
Und das ist jetzt schlimm weil ...?
-
Ein Thread ist nichts, das man ausfuehrt, sondern etwas, das man etwas ausfuehren laesst. Daher zu behaupten, ein Thread sei ein Runnable (= implements), ist voelliger Schwachsinn. Sollte daher eher so sein:
class Thread { private Runnable runnable; // ... }
Und dann haette Thread auch keine run()-Methode, die das Runnable im selben Thread ausfuehrt.
-
Und deswegen ist die ganze Java-Threads Implementierung ein einziger Design-Fail. Hätten wir das auch geklärt.
-
Das Interface ist ein Design-Fail. Jop. :p