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
Défini dans l'en-tête <condition_variable>
void notify_all_at_thread_exit ( std:: condition_variable & cond,
std:: unique_lock < std:: mutex > lk ) ;
(depuis C++11)

notify_all_at_thread_exit fournit un mécanisme pour notifier aux autres threads qu'un thread donné a complètement terminé, incluant la destruction de tous les objets thread_local . Il fonctionne comme suit :

  • La propriété du verrou précédemment acquis lk est transférée vers le stockage interne.
  • L'environnement d'exécution est modifié de telle sorte que lorsque le thread actuel se termine, la variable de condition cond est notifiée comme si par lk. unlock ( ) ;
    cond. notify_all ( ) ;
    .

Le déverrouillage implicite lk. unlock ( ) est séquencé après la destruction de tous les objets ayant une durée de stockage locale au thread associés au thread courant.

Si l'une des conditions suivantes est satisfaite, le comportement est indéfini :

  • lk n'est pas verrouillé par le thread appelant.
  • Si d'autres threads attendent également sur cond , lk. mutex ( ) est différent du mutex déverrouillé par les fonctions d'attente ( wait , wait_for et wait_until ) appelées sur cond par ces threads.

Table des matières

Notes

Un effet équivalent peut être obtenu avec les fonctionnalités fournies par std::promise ou std::packaged_task .

Le verrou fourni lk est maintenu jusqu'à la fin du thread. Une fois cette fonction appelée, aucun autre thread ne peut acquérir le même verrou pour attendre sur cond . Si certains threads attendent sur cette variable de condition, assurez-vous que la condition attendue soit satisfaite tout en maintenant le verrou sur lk , et que ce verrou ne soit pas relâché et réacquis avant d'appeler notify_all_at_thread_exit pour éviter toute confusion due à des réveils intempestifs dans d'autres threads.

Dans des cas d'utilisation typiques, cette fonction est la dernière chose appelée par un thread détaché.

Paramètres

cond - la variable de condition à notifier à la fin du thread
lk - le verrou associé à la variable de condition cond

Valeur de retour

(aucun)

Exemple

Ce fragment de code partiel illustre comment notify_all_at_thread_exit peut être utilisé pour éviter d'accéder aux données qui dépendent des variables locales de thread pendant que ces variables locales de thread sont en cours de destruction :

#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");
}

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement tel que publié Comportement corrigé
LWG 2140 C++11 l'appel à notify_all_at_thread_exit
synchronisé avec les appels aux fonctions en attente sur cond
mise à jour de l'exigence
de synchronisation

Voir aussi

définit le résultat à une valeur spécifique tout en délivrant la notification uniquement à la fin du thread
(fonction membre publique de std::promise<R> )
exécute la fonction en garantissant que le résultat est prêt uniquement lorsque le thread actuel se termine
(fonction membre publique de std::packaged_task<R(Args...)> )