Namespaces
Variants

std:: condition_variable

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
condition_variable
(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>
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 :

  1. Acquérir un std::mutex (généralement via std::lock_guard ).
  2. Modifier la variable partagée tant que le verrou est détenu.
  3. 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 :

  1. Acquérir un std:: unique_lock < std:: mutex > sur le mutex utilisé pour protéger la variable partagée.
  2. Effectuer l'une des opérations suivantes :
  1. Vérifiez la condition, au cas où elle aurait déjà été mise à jour et notifiée.
  2. 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).
  3. Vérifiez la condition et reprenez l'attente si elle n'est pas satisfaite.
ou :
  1. 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

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)
implémente un wrapper de propriété de mutex déplaçable
(modèle de classe)