Namespaces
Variants

std:: notify_all_at_thread_exit

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
notify_all_at_thread_exit
(C++11)
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
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...)> )