std:: notify_all_at_thread_exit
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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...)>
)
|