Aufrufen einer Methode als eigener Thread
-
#include <string> #include <iostream> #include <thread> using namespace std; class test { public: test() { printf("test"); }; int call() { printf("call"); return 0; }; private: }; int main (void) { thread t1(&test::call, test(10)); t1.join(); }
In diesem Fall passiert genau das. Nur wie kann ich die Methode call() Aufrufen ohne dabei immer ein neues Objekt zu erstellen?
Also ich will zuerst ein Objekt erstellen:test obj();
und dann die Methode call() als eigenständigen Thread aufrufen?
Wie geht das?
Danke Gruß
-
Das geht z.B. mit
bind
:object a; std::thread t(std::bind(&object::function, &a));
-
Und wie kann ich für das nachfolgende Array von Objekten.
test obj[10];
Jeweils ein Thread öffnen und call aufrufen?
Danke
-
Jodocus schrieb:
Das geht z.B. mit
bind
:object a; std::thread t(std::bind(&object::function, &a));
Danke für die Antwort.
Ich verstehe nur nicht ganz was a sein soll?
-
Dein Objekt.
-
Drum schrieb:
und dann die Methode call() als eigenständigen Thread aufrufen?
Ist das wirklich eine gute Idee?
Auf jedenfall sollte sicher gestellt sein, dass das Objekt dessen Funktion du benutzt länger lebt als der Thread selbst.Oder wenn du im selben scope bist solltest du den Thread wieder joinen.
P.S.: KA wie es mit printf ist aber std::cout z.b. muss mit einem Mutex abgesichert werden, wenn mehrere Threads zur gleichen Zeit darauf rumrennen.
-
Ruvi schrieb:
P.S.: KA wie es mit printf ist aber std::cout z.b. muss mit einem Mutex abgesichert werden, wenn mehrere Threads zur gleichen Zeit darauf rumrennen.
Ab C++11 muss man das nicht mehr.
-
Danke für die Antworten!! Ersten Problem gelöst!
Zweites:
Wie kann ich für das nachfolgende Array von Objekten.
test obj[10];
Jeweils ein Thread öffnen und call aufrufen?
-
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)
-
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)
Was passiert, wenn in call eine Exception geworfen wird oder der Constructor der threads eine exception wirft, weil er keine weiteren Threads mehr erstellen kann?
Du brauchst auch noch einen rudimentären thread_guard oder besser einen scoped_thread der die bereits erstellten Threads (via RAII)wieder joined, wenn sie joinable sind.Gerade multithreading ist ein Thema, bei dem man sich schnell den Fuß wegschiessen kann.
Ich würde mich an deiner Stelle(Thread_Author) vielleicht nochmal näher damit beschäftigen.
Das ist wirklich nichts was man mittels try and error lernen sollte.
-
Ruvi schrieb:
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)
Wass passiert, wenn in call eine Exception geworfen oder der Constructor der threads eine exception wirft, weil er keine weiteren Threads mehr erstellen kann?
Du brauchst auch noch einen rudimentären thread_guard oder einen scoped_thread der die bereits erstellten Threads wieder joined, wenn sie joinable sind.Gerade multithreading ist ein Thema, bei dem man sich schnell den Fuß wegschiessen kann.
Ich würde mich an deiner Stelle(Thread_Author) vielleicht nochmal näher damit beschäftigen.Danke für die Antworten!!
Deswegen habe ich auch die Frage hier gestellt?
-
Drum schrieb:
Deswegen habe ich auch die Frage hier gestellt?
Ich wühle mich gerade durch ein Buch das C++ Multithreading mit den neuen C++11 threads behandelt.
http://www.amazon.de/C-Concurrency-Action-Anthony-Williams/dp/1933988770/ref=sr_1_3?ie=UTF8&qid=1422370355&sr=8-3&keywords=concurrencyDas Buch hat 528 Seiten, ich bin mir nicht ob man in einem Forum das Thema so detailliert wie nötig behandeln kann.
Ein simples Beispiel aus dem Buch (Habe das Buch gerade nicht zur Hand aber ich hoffe ich habe es richtig aus dem Gedächtnis geschrieben):
class scoped_thread{ private: std::thread t_; public: explicit scoped_thread(std::thread t) : t_(std::move(t)) { //Könnte man auch mit einem assert machen. if(!t_.joinable()) throw(std::logical_error("No thread"); } ~scoped_thread() { t_.join(); } //copy und assignment operator noch deleten. };
-
Leider ist Multithreading in C++ nur extrem low-level möglich. thread und scoped_thread sind ein klares Zeichen dafür.
Alles was du eigentlich machen willst, sind einige von einander unabhängige Tasks ausführen. Jeder bessere Sprache bietet da Tasks und Task-Scheduling oder so an. Damit wird der Code abstrakter (du willst Tasks ausführen, nicht Thread-Management betreiben), man macht weniger Fehler und der Code wird performanter (da es Threadpools und so ermöglichst).
In C++ geht das nicht. Entweder ist es nicht vorhanden, oder völlig kaputt (std::async).
Deshalb kann ich zum Multithreading leider C++ nicht empfehlen. Wenn du bei einer Systemsprache bleiben willst, empfehle ich Rust.
-
Joa. Keine Ahnung hoam wie weit das Projekt des TE schon ist und wofür er das macht, aber gleich mal vorschlagen, 'ne andere (und noch dazu eine noch experimentelle) Programmiersprache zu benutzen, wa? Diese Rust-Manie geht mir langsam richtig aufn Keks.
-
müssen schrieb:
man macht weniger Fehler und der Code wird performanter (da es Threadpools und so ermöglichst).
In C++ geht das nicht. Entweder ist es nicht vorhanden, oder völlig kaputt (std::async).
Deshalb kann ich zum Multithreading leider C++ nicht empfehlen. Wenn du bei einer Systemsprache bleiben willst, empfehle ich Rust.
Naja um mal eine Lanze für C++ zu brechen, Threadpools können auch in C++ implementiert werden und es gibt Tonnen von multigethreadetem C++ Code in der Welt.
Ich stimme allerdings zu das Multithreading in C++ sehr komplex ist und man muss sehr darauf achten was man tut, um sicheren Code zu produzieren.Was Rust angeht: "Where is no such a thing as a free lunch." , deswegen gibt es C++ auch seit über 35 Jahren.
P.S.: Meine persönliche Abneigung gegen jede neue "Killersprache" die wöchentlich auf den Markt geworfen wird mag meine Haltung möglicherweise verfestigen.
P.P.S: Bei Rust immer schön auf die * achten.
"* In theory. Rust is a work-in-progress and may do anything it likes up to and including eating your laundry. "
-
Die Moderation kann hier ruhig häufiger mal Posts verschieben.
Z.B. finde ich müssens Beitrag und die Antworten wären gut in RudP aufgehoben.Hier ist's nämlich offtopic und wenn's gelöscht wird mault er rum.
Der vielsagende Titel "Ich empfehle Rust" würde seinen Beitrag angemessen zusammenfassen und sein Anliegen zum Ausdruck bringen.
-
Du brauchst bei std::thread kein std::bind, der Ctor macht das bereits selbst.
-
Kellerautomat schrieb:
Du brauchst bei std::thread kein std::bind, der Ctor macht das bereits selbst.
Ja, aber nur, wenn du
std::ref
benützt. Das wäre dann eine der vielen anderen Möglichkeiten.Edit: Stimmt, man kann's natürlich auch als Pointer übergeben, bin noch etwas von den Workarounds um einen alten VS-Bug geschädigt.
-
Jodocus schrieb:
Kellerautomat schrieb:
Du brauchst bei std::thread kein std::bind, der Ctor macht das bereits selbst.
Ja, aber nur, wenn du
std::ref
benützt. Das wäre dann eine der vielen anderen Möglichkeiten.Geht auch ohne ref. Das std::bind von dir hat gar keine Wirkung.
Jodocus schrieb:
Joa. Keine Ahnung hoam wie weit das Projekt des TE schon ist und wofür er das macht, aber gleich mal vorschlagen, 'ne andere (und noch dazu eine noch experimentelle) Programmiersprache zu benutzen, wa?
Es ging ums Lernen von Multithreading, da ist es doch wohl egal, welche Programmiersprache er nutzt.
Die Sache mit C++ ist halt:
std::thread/std::async/... sind (in der jetztigen Form) unbrauchbar.
TBB und ein paar andere Bibliotheken sind brauchbar, aber kompliziert.Andererseits ist Multithreading in einigen anderen Sprachen (ich lege mich diesmal nicht genauer fest) sicherer und besser unterstützt mit Taskpools und Channels anstatt Threads und Mutexen.
-
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?