Namespaces
Variants

std::condition_variable_any:: notify_one

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 notify_one ( ) noexcept ;
(depuis C++11)

Si des threads sont en attente sur * this , l'appel à notify_one débloque l'un des threads en attente.

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é.

Le thread notifiant n'a pas besoin de détenir le verrou sur le même mutex que celui détenu par le(s) thread(s) en attente ; en fait, cela constitue une pessimisation, puisque le thread notifié serait immédiatement bloqué à nouveau, attendant que le thread notifiant libère le verrou. Cependant, certaines implémentations (en particulier de nombreuses implémentations de pthreads) reconnaissent cette situation et évitent ce scénario de « se dépêcher puis attendre » en transférant le thread en attente de la file d'attente de la variable condition directement vers la file d'attente du mutex lors de l'appel de notification, sans le réveiller.

La notification sous verrou peut néanmoins être nécessaire lorsqu'une planification précise des événements est requise, par exemple si le thread en attente quitterait le programme si la condition est satisfaite, provoquant la destruction de la variable de condition du thread notifiant. Un réveil erroné après le déverrouillage du mutex mais avant la notification entraînerait un appel de notification sur un objet détruit.

Exemple

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
std::condition_variable_any cv;
std::mutex cv_m;
int i = 0;
bool done = false;
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cout << "Waiting... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cout << "...finished waiting; i == " << i << '\n';
    done = true;
}
void signals()
{
    std::this_thread::sleep_for(200ms);
    std::cout << "Notifying falsely...\n";
    cv.notify_one(); // waiting thread is notified with i == 0.
                     // cv.wait wakes up, checks i, and goes back to waiting
    std::unique_lock<std::mutex> lk(cv_m);
    i = 1;
    while (!done) 
    {
        std::cout << "Notifying true change...\n";
        lk.unlock();
        cv.notify_one(); // waiting thread is notified with i == 1, cv.wait returns
        std::this_thread::sleep_for(300ms);
        lk.lock();
    }
}
int main()
{
    std::thread t1(waits), t2(signals);
    t1.join(); 
    t2.join();
}

Sortie possible :

Waiting... 
Notifying falsely...
Notifying true change...
...finished waiting; i == 1

Voir aussi

notifie tous les threads en attente
(fonction membre publique)
Documentation C pour cnd_signal