[Problem] boost::thread Programmstruktur
-
Hallo Leute,
ich habe hier ein kleines Problem mit meiner Programmstruktur. Ich habe einen Daemon der sich von einem Job-Server neue Jobs holt und diese dann abarbeitet.
Nun möchte ich das ganze so erweitern, das der Daemon mehrere Jobs aufeinmal bearbeiten kann. Ich möchte das jeder Job in einem eigenen Thread abgearbeitet wird.
Ich habe eine große While-Loop welche immer prüft ob neue Jobs vorhanden sind.Derzeit funktioniert das so. Ich habe einen Thread-Pool (thread_group). In der Main-Loop werden solange Jobs geholt bis entweder keiner mehr vorhanden ist, oder der Thread-Pool voll ist.
Wenn das erledigt ist, joine ich alle threads mit thread_group::join_all(). Und genau hier ist das Problem. thread_group::join_all() ist blocking, was bedeutet, das selbst wenn 3/4 threads fertig sind alles noch blockiert,
was in meinen Augen eine Verschwendung von Zeit und Ressourcen ist.Wie kann ich also threads asynchron joinen? Die threads müssen untereinander nicht synchronisiert werden (sie teilen sich keine Ressourcen). Ich finde einfach kein Asynchrones äquivalent zu boost::thread::join().
Kann mir eventuell jemand einen Tipp geben, wie man das am besten lösen kann? Meine Boost Kenntnisse sind leider noch nicht so tiefgehend und mir fehlen schlicht weg die Optionen welche ich habe. Kann man da eventuell was mit boost::asio machen?
Danke für die Hilfe
so long
-
Mit der Boost-Bibliothek kenn ich mich nicht aus, aber in C++11 gibt es in std::future ein std::async(..), was unter bestimmen Bedingungen einen neuen Thread startet. Du wartest auf so einen std::async thread mit get().
Ist es sowas was du suchst?
#include <future> #include <iostream> int main() { auto res=std::async(std::launch::async,[]{int sum=0; for(int i=0;i<50;++i)sum+=i; return sum;}); std::cout<<res.get(); }
-
Fl0 schrieb:
Mit der Boost-Bibliothek kenn ich mich nicht aus, aber in C++11 gibt es in std::future ein std::async(..), was unter bestimmen Bedingungen einen neuen Thread startet. Du wartest auf so einen std::async thread mit get().
Da die C++11-Threads vomn Design her ziemlich eng an die Boost-Threads angelehnt wurden, wird es dies dort sicherlich auch geben. Jedoch bin ich ebenfalls überfragt, wie dieses Feature dort genau heißt.
-
SeppJ schrieb:
Da die C++11-Threads vomn Design her ziemlich eng an die Boost-Threads angelehnt wurden, wird es dies dort sicherlich auch geben. Jedoch bin ich ebenfalls überfragt, wie dieses Feature dort genau heißt.
Das dachte ich mir auch, weshalb ich das überhaupt gepostet habe. Aber:
Boost schrieb:
Future
The following features will be included in next releases.Complete the C++11 missing features, in particular
#4710 Missing async().
-
Danke für Eure schnelle Hilfe. Aber ich vermute das mein Problem simpler ist.
Mir war nicht klar das ein boost::thread::join() optional ist. Da ich nichts blockieren will, lass ich einfach den join weg und wusch es funktioniert. Ich habe das mit dem Join in der Doku so verstanden, das der Thread erst erstellt wird, wenn ich den Join mache und habe auch schon geschimpft was das sein soll. Ich habe da einfach etwas falsch interpretiert.Jedoch werde ich mir das was Ihr geschrieben habt auch angucken interessant ist es definitiv.
PS: Die Boost Doku ist teilweise die Hölle

so long
-
Ich würde für sowas boost.asio benutzen. Das Hat das ganze Zeugs fürs Queuen der Jobs und das Verteilen auf Threads schon fertig drin.
-
Ich vermute mal, dass du bei einem leeren Pool von Threads nicht blockst und dein Prozessor (bzw. ein Kern), auch wenn gar kein Task abgearbeitet wird, auf 100% läuft...
-
Tachyon schrieb:
Ich würde für sowas boost.asio benutzen. Das Hat das ganze Zeugs fürs Queuen der Jobs und das Verteilen auf Threads schon fertig drin.
Hallo Tachyon,
meinst du alle Operationen dich ich verteilen will (ist nur eine Funktion) einfach via boost::asio asynchron ausführen und boost::asio verteilt dann alles via Threads, falls notwenig selbständig? Falls ja, taugt das was, das ganze boost::asio zu überlassen?
-
boost::asio verteilt von selbst gar nix auf Threads.
In der vorgeschlagenen Verwendung ist es nicht viel mehr als fancy Task-Queue.Die Worker-Threads musst du dabei selbst bereitstellen. D.h. du kannst auch selbst entscheiden wie viele Threads gleichzeitig werken sollen, was die für ne Priorität haben sollen etc.
Mir war nicht klar das ein boost::thread::join() optional ist.
Ab Boost 1.50.0 sollte man
thread::detachoderthread::joinaufrufen bevor man nenboost::threadüberschreibt (mit move) oder zerstört. Sonst ruft Boost nämlichstd::terminateauf.
Wenn du möchtest dass die Thread weiterlaufen in deinem Fall alsothread::detach.
-
Hallo hustbaer,
ich danke dir für die Erklärung, das Thema ist doch interessanter als ich gedacht habe. Ich werde mich damit mal etwas näher beschäftigen. Ein Einsatzgebiet ist ja auch schon vorhanden.
so long