Ich schreibe ein einfaches Programm zum Testen von Thread in C ++ 11, aber std::cout
funktioniert nicht wie erwartet.
einige der Ergebnisse:
%Vor% Ich habe Mutex zum Sperren von Threads verwendet, sodass ich nicht verstehen kann, warum zwei Threads std::cout
gleichzeitig ausführen.
Es scheint mir sehr verwunden. Kann irgendjemand erklären, was passiert!?!
Die Threads verwenden verschiedene mutex
Instanzen, da mutex
eine lokale Variable in der Funktion exec()
ist. Das Sperren von mutex
ist daher sinnlos, da jeder Thread seine eigene Sperre setzt mutex
, was zu keiner Synchronisation zwischen den Threads führt. Die gleiche mutex
-Instanz muss von den Threads verwendet werden, um eine Synchronisation zu erreichen.
Um den geposteten Code zu korrigieren, machen Sie mutex
zu einer Mitgliedsvariablen. Wenn jedoch ein anderes Printer
-Objekt erstellt wurde, gab es keine Synchronisierung zwischen Threads, die unterschiedliche Printer
-Instanzen verwendeten. In diesem Fall müsste mutex
eine static
-Membervariable sein, um die Synchronisation sicherzustellen:
Um sicherzustellen, dass ein mutex
immer freigegeben wird, verwenden Sie %, unabhängig davon, ob eine Funktion normal oder über eine Ausnahme beendet wird. co_de% :
Die angenommene Antwort ist korrekt. Es ist jedoch schön, Bedenken zu trennen:
std::cout
threadsicher zu drucken. Hier ist ein Dienstprogramm, das ich verwende, das sich darauf konzentriert, Argumente für std::cout
zu sammeln und sie unter einem static std::mutex
:
Dieser Code kann für andere Streams als std::cout
wiederverwendet werden, aber das obige ist darauf spezialisiert, nur std::cout
zu targetieren. Damit kann Ihre Printer::exec()
nun wesentlich vereinfacht werden:
Nun wird nicht nur Ihre Printer
cout
threadsicherer verwenden und wurde auch vereinfacht (zB muss nicht ihre eigene mutex
für cout
beibehalten), sondern all Ihre anderen Typen und Funktionen können auch cout
verwenden und alle zusammen sicher zusammenarbeiten. Die Funktion print
behält nun mutex
bei, und diese Tatsache wird von allen Clients von print
gekapselt.
Ich teile den Trick von Nicolás, gegeben in Diese Frage finde ich eleganter als die Implementierung von Howard Hinnant. Die Idee ist, ein temporäres ostringstream-Objekt zu erstellen und den Schutzcode auf den Destruktor zu setzen.
%Vor% Sie können es dann als reguläres std::cout
von jedem Thread verwenden:
Das Objekt sammelt Daten als reguläres std::ostringstream
. Sobald das Koma erreicht ist, wird das Objekt zerstört und alle gesammelten Informationen werden gelöscht.
Sie können eine globale std::mutex cout_mutex;
(irgendwo in Ihren Namespaces) in Betracht ziehen, die verwendet wird, um std::cout
output zu schützen. Stellen Sie sicher, dass Sie std::lock<std::mutex>
verwenden (Sie können also nicht vergessen, den Mutex und die Ausnahmesicherheit zu entsperren).
Tags und Links c++ multithreading c++11 mutex stdthread