std:: notify_all_at_thread_exit
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Definiert im Header
<condition_variable>
|
||
|
void
notify_all_at_thread_exit
(
std::
condition_variable
&
cond,
std:: unique_lock < std:: mutex > lk ) ; |
(seit C++11) | |
notify_all_at_thread_exit
bietet einen Mechanismus, um anderen Threads mitzuteilen, dass ein bestimmter Thread vollständig beendet wurde, einschließlich der Zerstörung aller
thread_local
Objekte. Es funktioniert wie folgt:
- Der Besitz des zuvor erworbenen Locks lk wird an internen Speicher übertragen.
-
Die Ausführungsumgebung wird so modifiziert, dass beim Beenden des aktuellen Threads die Bedingungsvariable
cond
benachrichtigt wird, als ob durch
lk.
unlock
(
)
;
cond. notify_all ( ) ; .
Das implizite lk. unlock ( ) ist sequenziert nach der Zerstörung aller Objekte mit thread local storage duration , die dem aktuellen Thread zugeordnet sind.
Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:
- lk wird nicht vom aufrufenden Thread gesperrt.
-
Falls andere Threads ebenfalls auf
cond
warten,
unterscheidet sich
lk.
mutex
(
)
vom Mutex, der durch die Wartefunktionen (
wait, wait_for und wait_until ) auf cond durch jene Threads entsperrt wurde.
Inhaltsverzeichnis |
Hinweise
Ein gleichwertiger Effekt kann mit den von std::promise oder std::packaged_task bereitgestellten Funktionen erzielt werden.
Der übergebene Lock
lk
wird gehalten, bis der Thread beendet wird. Sobald diese Funktion aufgerufen wurde, dürfen keine weiteren Threads denselben Lock mehr erwerben, um auf
cond
zu warten. Falls einige Threads auf diese Condition Variable warten, stellen Sie sicher, dass die Bedingung, auf die gewartet wird, erfüllt ist, während der Lock auf
lk
gehalten wird, und dass dieser Lock nicht freigegeben und vor dem Aufruf von
notify_all_at_thread_exit
wieder erworben wird, um Verwirrung durch falsche Wakeups in anderen Threads zu vermeiden.
In typischen Anwendungsfällen ist diese Funktion die letzte Aktion, die von einem abgetrennten Thread aufgerufen wird.
Parameter
| cond | - | die Bedingungsvariable, die beim Thread-Ende benachrichtigt werden soll |
| lk | - | die Sperre, die der Bedingungsvariablen cond zugeordnet ist |
Rückgabewert
(keine)
Beispiel
Dieses Codefragment veranschaulicht, wie
notify_all_at_thread_exit
verwendet werden kann, um den Zugriff auf Daten zu vermeiden, die von Thread-Lokalen abhängen, während diese Thread-Lokalen im Zerstörungsprozess sind:
#include <cassert> #include <condition_variable> #include <mutex> #include <string> #include <thread> std::mutex m; std::condition_variable cv; bool ready = false; std::string result; // some arbitrary type void thread_func() { thread_local std::string thread_local_data = "42"; std::unique_lock<std::mutex> lk(m); // assign a value to result using thread_local data result = thread_local_data; ready = true; std::notify_all_at_thread_exit(cv, std::move(lk)); } // 1. destroy thread_locals; // 2. unlock mutex; // 3. notify cv. int main() { std::thread t(thread_func); t.detach(); // do other work // ... // wait for the detached thread std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{ return ready; }); // result is ready and thread_local destructors have finished, no UB assert(result == "42"); }
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| LWG 2140 | C++11 |
der Aufruf von
notify_all_at_thread_exit
synchronisiert mit Aufrufen von Funktionen, die auf cond warten |
aktualisierte die Synchronisierungs-
anforderung |
Siehe auch
|
setzt das Ergebnis auf einen bestimmten Wert, während die Benachrichtigung nur beim Thread-Ende übermittelt wird
(öffentliche Elementfunktion von
std::promise<R>
)
|
|
|
führt die Funktion aus und stellt sicher, dass das Ergebnis erst bereit ist, wenn der aktuelle Thread beendet wird
(öffentliche Elementfunktion von
std::packaged_task<R(Args...)>
)
|