Namespaces
Variants

std::condition_variable:: wait

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
(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
void wait ( std:: unique_lock < std:: mutex > & lock ) ;
(1) (depuis C++11)
template < class Predicate >
void wait ( std:: unique_lock < std:: mutex > & lock, Predicate pred ) ;
(2) (depuis C++11)

wait provoque le blocage du thread actuel jusqu'à ce que la variable de condition soit notifiée ou qu'un réveil intempestif se produise. pred peut être optionnellement fourni pour détecter les réveils intempestifs.

1) Appelle atomiquement lock. unlock ( ) et se bloque sur * this .
Le thread sera débloqué lorsque notify_all() ou notify_one() est exécuté. Il peut également être débloqué de manière sporadique.
Lorsqu'il est débloqué, appelle lock. lock ( ) (pouvant se bloquer sur le verrou), puis retourne.
2) Équivalent à
while ( ! pred ( ) )
wait ( lock ) ;
.
Cette surcharge peut être utilisée pour ignorer les réveils intempestifs lors de l'attente qu'une condition spécifique devienne true .

Immédiatement après que wait retourne, lock. owns_lock ( ) est true , et lock. mutex ( ) est verrouillé par le thread appelant. Si ces postconditions ne peuvent être satisfaites [1] , appelle std::terminate .

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

  • lock. owns_lock ( ) est false .
  • lock. mutex ( ) n'est pas verrouillé par le thread appelant.
  • Si d'autres threads attendent également sur * this , lock. mutex ( ) est différent du mutex déverrouillé par les fonctions d'attente ( wait , wait_for et wait_until ) appelées sur * this par ces threads.
  1. Cela peut se produire si le nouveau verrouillage du mutex lève une exception.

Table des matières

Paramètres

lock - un verrou qui doit être verrouillé par le thread appelant
pred - le prédicat pour vérifier si l'attente peut être terminée
Exigences de type
-
Predicate doit satisfaire aux exigences de FunctionObject .
-
pred ( ) doit être une expression valide, et son type et sa catégorie de valeur doivent satisfaire aux BooleanTestable exigences.

Exceptions

1) Ne lance rien.
2) Toute exception levée par pred .

Notes

Les effets de notify_one() / notify_all() et chacune des trois parties atomiques de wait() / wait_for() / wait_until() (déverrouillage+attente, réveil et verrouillage) se produisent dans un ordre total unique qui peut être considéré comme l'ordre de modification d'une variable atomique : cet ordre est spécifique à cette variable conditionnelle individuelle. Cela rend impossible, par exemple, que notify_one() soit retardé et débloque un thread qui a commencé à attendre juste après l'appel à notify_one() ait été effectué.

Exemple

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
std::condition_variable cv;
std::mutex cv_m; // Ce mutex est utilisé à trois fins :
                 // 1) synchroniser les accès à i
                 // 2) synchroniser les accès à std::cerr
                 // 3) pour la variable de condition cv
int i = 0;
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "En attente... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cerr << "...fin de l'attente. i == 1\n";
}
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Notification...\n";
    }
    cv.notify_all();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        i = 1;
        std::cerr << "Nouvelle notification...\n";
    }
    cv.notify_all();
}
int main()
{
    std::thread t1(waits), t2(waits), t3(waits), t4(signals);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

Sortie possible :

En attente...
En attente...
En attente...
Notification...
Nouvelle notification...
...fin de l'attente. i == 1
...fin de l'attente. i == 1
...fin de l'attente. i == 1

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 publié Comportement corrigé
LWG 2114
( P2167R3 )
C++11 la convertibilité vers bool était trop faible pour refléter les attentes des implémentations exigences renforcées
LWG 2135 C++11 le comportement était peu clair si lock. lock ( ) lance une exception appelle std::terminate dans ce cas

Voir aussi

bloque le thread actuel jusqu'à ce que la variable de condition soit réveillée ou après la durée de temporisation spécifiée
(fonction membre publique)
bloque le thread actuel jusqu'à ce que la variable de condition soit réveillée ou jusqu'à ce que le point temporel spécifié soit atteint
(fonction membre publique)
Documentation C pour cnd_wait

Liens externes

The Old New Thing article : Réveils intempestifs dans les variables de condition Win32.