Aufrufen einer Methode als eigener Thread
-
Ruvi schrieb:
müssen schrieb:
Die Sache mit C++ ist halt:
std::thread/std::async/... sind (in der jetztigen Form) unbrauchbar.Sorry, aber so eine Behauptung ist ohne Begründung schlicht nicht zulässig.
Warum ist deiner Meinung nach Std::thread und Std::asynchron unbrauchbar?Plain Threads are the GOTO of todays computing
Bspw., hab jetzt nicht genau im Kopf, ob das genau dadrauf eingeht.
-
Ruvi schrieb:
müssen schrieb:
Ab C++11 muss man das nicht mehr.
Ja, stimmt Du hast recht. Ich habe mich unglücklich ausgedrückt.
patrick246 schrieb:
Wir legen eben für jedes Element im Array einen Thread an. Anschließend warten wir darauf, bis diese fertig sind.
std::vector<std::thread> threads; for(auto& o : obj) { threads.emplace_back(std::bind(&test::call, &o)); } for(auto& t : threads) { t.join(); }
(ungetestet)
.
Hey leute kann mir jemand vlt. die Syntax erklären wieso benutzt man '&' Operator und ':' und '::' irgendwie ist mir das ganze so richtig nicht geläufig unter C++. Bei Klasse nehme ich '::' bei der Deklaration und bei namespaces nehme ich auch '::' aber in diesem Fall
Danke Gruß
-
Also soweit ich das jetzt verstehe ist das sowas:
for(std::vector<test>::iterator it = objs.begin(); it != objs.end() ; it++)
OK das müsste die for Anweisung sein.
-
for(auto x : container){}
Ist das sogenannte Range-Based-For, oder in anderen auch Sprachen auch als foreach bekannt (z.B. C#, in Java wird es fast genau wie in C++ geschrieben). Das iteriert über deinen gesamten Container (genauer gesagt, über den gesamten Bereich, den die rechte Seite aufgrund von Iteratoren[begin/end] darbietet). Das 'x' ist jeweils das aktuelle Objekt im Container und kann nach belieben ein Value, eine Referenz oder auch das gleich in const sein. Nachteil ist, dass du keinen Index oder den unterliegenden Iterator mehr zur Verfügung hast, was man manchmal (selten) braucht.
Die :: bennen die Methode einer Klasse:
#include <iostream> class Foo { public: void meth(){ std::cout << "Meth" << std::endl; } static void smeth(){ std::cout << "SMeth" << std::endl; } }; int main() { Foo f; f.meth(); (f.*(&Foo::meth))(); Foo::smeth(); }
Das solltest du kennen. Wenn du jetzt Funktionszeiger dazu nimmst, dann reicht nicht den Methodennamen (also meth) zu schreiben, sondern du musst dazuschreiben, dass es um die Methode der Klasse Foo geht -> Fooo::meth. Und da wir die Adresse haben wollen brauchen wir das & davor -> &Foo::meth.
Um die Methode allerdings aufzurufen brauchen wir noch ein Object...Und du siehst, das sieht gar nicht mal so schön aus...
-
Skym0sh0 schrieb:
for(auto x : container){}
Wichtig zu wissen ist auch, dass das insert/delete von Elementen innerhalb einer ranged-based for undefined behavior verursacht.
-
Danke soweit alles verstanden bis auf:
for(auto& t : threads)
Wieso muss es eine Referenz sein?
-
Muss es nicht. Sonst wird eben jeder einzelne Wert in diese Variable kopiert. Wenn du das nicht willst (bzw. kannst, denn manche Objekte kann man nicht kopieren), z.B. weil du die Werte verändern möchtest, nimmst du Referenzen.
-
Naja ohne kriege ich ein Fehler das er auf eine gelöschte FKT zugreift.
Und diese Zeile:
threads.emplace_back(std::bind(&test::call, &o));
ist doch für mich nicht richtig verständlich. Wieso fügen wir am ende vom container von threads binds ?! ein ?!
-
Grnom123 schrieb:
Wieso fügen wir am ende vom container von threads binds ?! ein ?!
Das bind kannst du weglassen.
Und die Frage sollte sich klären, wenn du emplace_back nachschaust.
-
bindungsenergie schrieb:
Grnom123 schrieb:
Wieso fügen wir am ende vom container von threads binds ?! ein ?!
Das bind kannst du weglassen.
Und die Frage sollte sich klären, wenn du emplace_back nachschaust.Habe ich schon davor nachgeschaut? Ich füge ein Element am Ende des Containers ein?
-
Grnom123 schrieb:
bindungsenergie schrieb:
Grnom123 schrieb:
Wieso fügen wir am ende vom container von threads binds ?! ein ?!
Das bind kannst du weglassen.
Und die Frage sollte sich klären, wenn du emplace_back nachschaust.Habe ich schon davor nachgeschaut? Ich füge ein Element am Ende des Containers ein?
Jain, du konstruierst mit emplace_back IM vector ein Objekt.
pushback erstellt erst das Objekt und kopiert/moved es dann in den Vector rein.
Pushback bietet Dir also eine strong exception gurantee während emplace_back das Objekt direkt im Vector erstellt.Vielleicht ist diese Schreibweise unter Umständen anschaulicher:
threads.emplace_back(thread(std::bind(&test::call, &o)));
Du fügst also keinen bind in den Vector ein sondern du erstellst im Vector einen thread mit dem bind als thread constructor parameter.
-
Ruvi schrieb:
Ja, wobei mir der Zusatz noch besser gefällt:
Inserts a new element at the end of the vector, right after its current last element.Der entscheidende Zusatz kommt kurz danach:
This new element is constructed in place using args as the arguments for its constructor.
D.h. es wird sowas wie
push_back(std::thread(args))
, hierpush_back(std::thread(std::bind(&test::call, &o)))
aufgerufen.Da sieht man dann auch, dass std::bind unnötig ist:
push_back(std::thread(&test::call, &o))
oder
emplace_back(&test::call, &o)
tuts deshalb auch.