Thread mit Hauptthread synchronisieren
-
Hi,
ich möchte, dass wenn mein Hauptthread einen weiteren Thread startet der Hauptthread so lange wartet bis er eine Benachrichtigung des gestarteten Threads erhält (was nicht impiliziert, dass der neu gestartete Thread zu Ende ist). Wie mache ich das am besten?
-
Wenn du es was sauberer nach Logik trennst, kannst du eventuell ganz gut Futures (mit std::async) nutzen.
Was hast du denn vor?
@Tipp: Rechtschreibung, Grammatik und Zeichensetzung sind nicht nur eine Erfindung und Verschwörung der Regierung...
-
Im Mainthread einen std::mutex locken, Thread starten, im Mainthread erneut den Mutex locken, im Thread den Mutex freigeben.
-
nwp3 schrieb:
Im Mainthread einen std::mutex locken, Thread starten, im Mainthread erneut den Mutex locken, im Thread den Mutex freigeben.
Geht nicht.
Mutexen sind normalerweise "owned", können also nur in dem Thread freigegeben werden wo sie auch gelockt wurden. Versuche es anders zu machen Enden üblicherweise in einer Exception (oder auchabort, je nach Library -- was der C++ Standard vorschreibt, wenn überhaupt etwas, weiss ich nicht).Wenn dann müsste man schon nen "(unowned) binary semaphore" verwenden.
Geht aber auch mit ner Mutex + Condition-Variable + State-Variable (initializing/initialized/initialization_failed). Ist etwas mehr Code, aber mMn. besser verständlich. Ich mag "unowned" Synchronization-Primitives nicht sonderlich - die fühlen sich zu unnatürlich an.
-
hustbaer schrieb:
Mutexen sind normalerweise "owned", können also nur in dem Thread freigegeben werden wo sie auch gelockt wurden.
Guter Punkt. Das ist etwas was ich nie verstanden habe. Soweit ich das sehe kostet es extra Aufwand um das durchzusetzen und ist einfach nur schlecht. Der pthread-Standard sagt das auch, aber die Implementationen halten sich üblicherweise nicht dran. thread.wakeup() gibt es nicht, promise und future sind nicht wiederverwendbar... std::condition_variable scheint wirklich der einzige Standardweg zu sein. Vielleicht kann man mit std::packaged_task::reset was bauen.
-
Eine Condition wäre die Lösung. Also etwa im pseudocode:
bool ready = false; Condition cond; Mutex mutex; startThread ... // main thread: mutex.lock(); ready = true; cond.signal(); mutex.unlock(); // sub thread: mutex.lock(); while (!ready) cond.wait(mutex); mutex.unlock(); // isch habe fertig
-
was Du willst ist ein Semaphor
boost::interprocess hat das. Warum es das nicht im C++11 gibt ist mir schleierhaft.
-
lllla schrieb:
Hi,
ich möchte, dass wenn mein Hauptthread einen weiteren Thread startet der Hauptthread so lange wartet bis er eine Benachrichtigung des gestarteten Threads erhält (was nicht impiliziert, dass der neu gestartete Thread zu Ende ist). Wie mache ich das am besten?
Hört sich für mich nach std::promise an. Das Beispiel was gegeben ist passt auch noch perfekt zu deinem Problem
EDIT:
1. Für jede Benachrichtigung brauchst du (leider) ein neues promise objekt, da man std::promise nicht resetten kann. D.h. wenn du deinen Hauptthread immer wieder benachrichtigen musst eignet es sich nur bedingt.
2. Wenn du Betriebssystemspezifisch arbeiten kannst, womöglich eleganter, insbesondere dann wenn der Hauptthread oft er benachrichtigt werden mussfloorball
-
nwp3 schrieb:
hustbaer schrieb:
Mutexen sind normalerweise "owned", können also nur in dem Thread freigegeben werden wo sie auch gelockt wurden.
Guter Punkt. Das ist etwas was ich nie verstanden habe. Soweit ich das sehe kostet es extra Aufwand um das durchzusetzen und ist einfach nur schlecht.
Ja, kostet extra Aufwand es durchzusetzen, aber minimal.
Und es ist nicht einfach nur schlecht sondern einfach nur gut. Es vermeidet Fehler.Man kann Semaphore zwar für viele Dinge verwenden, aber die Lösungen die dabei rauskommen sind selten elegant oder einfach zu verstehen. Mutexe + Condition-Variablen sind viel einfacher zu behirnen und führen zu Code der viel "natürlicher" ausdrückt was man eigentlich machen möchte.
floorball schrieb:
Hört sich für mich nach std::promise an. Das Beispiel was gegeben ist passt auch noch perfekt zu deinem Problem
Das ist gut. An
std::promisehatte ich gar nicht gedacht.