std:: condition_variable
|
Défini dans l'en-tête
<condition_variable>
|
||
|
class
condition_variable
;
|
(depuis C++11) | |
std::condition_variable
est un primitif de synchronisation utilisé avec un
std::mutex
pour bloquer un ou plusieurs threads jusqu'à ce qu'un autre thread modifie à la fois une variable partagée (la
condition
) et notifie le
std::condition_variable
.
Le thread qui a l'intention de modifier la variable partagée doit :
- Acquérir un std::mutex (généralement via std::lock_guard ).
- Modifier la variable partagée tant que le verrou est détenu.
-
Appeler
notify_one
ou
notify_all
sur le
std::condition_variable(peut être effectué après avoir relâché le verrou).
Même si la variable partagée est atomique, elle doit être modifiée en détenant le mutex pour correctement publier la modification au thread en attente.
Tout thread qui souhaite attendre sur une
std::condition_variable
doit :
- Acquérir un std:: unique_lock < std:: mutex > sur le mutex utilisé pour protéger la variable partagée.
- Effectuer l'une des opérations suivantes :
-
- Vérifiez la condition, au cas où elle aurait déjà été mise à jour et notifiée.
-
Appelez
wait
,
wait_for
, ou
wait_until
sur le
std::condition_variable(libère atomiquement le mutex et suspend l'exécution du thread jusqu'à ce que la variable condition soit notifiée, qu'un délai d'attente expire, ou qu'un réveil intempestif se produise, puis acquiert atomiquement le mutex avant de retourner). - Vérifiez la condition et reprenez l'attente si elle n'est pas satisfaite.
- ou :
- Utilisez la surcharge avec prédicat de wait , wait_for , et wait_until , qui effectue les trois mêmes étapes.
std::condition_variable
fonctionne uniquement avec
std::
unique_lock
<
std::
mutex
>
, ce qui permet une efficacité maximale sur certaines plateformes.
std::condition_variable_any
fournit une variable conditionnelle qui fonctionne avec tout objet
BasicLockable
, tel que
std::shared_lock
.
Les variables de condition permettent l'invocation concurrente des fonctions membres wait , wait_for , wait_until , notify_one et notify_all .
La classe
std::condition_variable
est un
StandardLayoutType
. Elle n'est pas
CopyConstructible
,
MoveConstructible
,
CopyAssignable
, ni
MoveAssignable
.
Table des matières |
Types imbriqués
| Nom | Définition |
native_handle_type
|
défini par l'implémentation |
Fonctions membres
|
construit l'objet
(fonction membre publique) |
|
|
détruit l'objet
(fonction membre publique) |
|
|
operator=
[deleted]
|
non assignable par copie
(fonction membre publique) |
Notification |
|
|
notifie un thread en attente
(fonction membre publique) |
|
|
notifie tous les threads en attente
(fonction membre publique) |
|
Attente |
|
|
bloque le thread courant jusqu'à ce que la variable de condition soit réveillée
(fonction membre publique) |
|
|
bloque le thread courant jusqu'à ce que la variable de condition soit réveillée ou après la durée de timeout spécifiée
(fonction membre publique) |
|
|
bloque le thread courant 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) |
|
Gestionnaire natif |
|
|
retourne le gestionnaire natif
(fonction membre publique) |
|
Exemple
std::condition_variable
est utilisé en combinaison avec un
std::mutex
pour faciliter la communication entre threads.
#include <condition_variable> #include <iostream> #include <mutex> #include <string> #include <thread> std::mutex m; std::condition_variable cv; std::string data; bool ready = false; bool processed = false; void worker_thread() { // wait until main() sends data std::unique_lock lk(m); cv.wait(lk, []{ return ready; }); // after the wait, we own the lock std::cout << "Worker thread is processing data\n"; data += " after processing"; // send data back to main() processed = true; std::cout << "Worker thread signals data processing completed\n"; // manual unlocking is done before notifying, to avoid waking up // the waiting thread only to block again (see notify_one for details) lk.unlock(); cv.notify_one(); } int main() { std::thread worker(worker_thread); data = "Example data"; // send data to the worker thread { std::lock_guard lk(m); ready = true; std::cout << "main() signals data ready for processing\n"; } cv.notify_one(); // wait for the worker { std::unique_lock lk(m); cv.wait(lk, []{ return processed; }); } std::cout << "Back in main(), data = " << data << '\n'; worker.join(); }
Sortie :
main() signals data ready for processing Worker thread is processing data Worker thread signals data processing completed Back in main(), data = Example data after processing
Voir aussi
|
(C++11)
|
fournit une variable de condition associée à n'importe quel type de verrou
(classe) |
|
(C++11)
|
fournit une fonction d'exclusion mutuelle de base
(classe) |
|
(C++11)
|
implémente un wrapper de propriété de mutex strictement basé sur la portée
(modèle de classe) |
|
(C++11)
|
implémente un wrapper de propriété de mutex déplaçable
(modèle de classe) |