Namespaces
Variants

std::condition_variable:: 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 ;
(seit C++11)

Falls Threads auf * this warten, hebt der Aufruf von notify_one einen der wartenden Threads auf.

Hinweise

Die Effekte von notify_one() / notify_all() und jeder der drei atomaren Teile von wait() / wait_for() / wait_until() (Entsperren+Warten, Aufwecken und Sperren) finden in einer einzigen Gesamtordnung statt, die als Modifikationsreihenfolge einer atomaren Variable betrachtet werden kann: Die Reihenfolge ist spezifisch für diese individuelle Condition Variable. Dies macht es unmöglich, dass notify_one() beispielsweise verzögert wird und einen Thread entsperrt, der gerade nach dem Aufruf von notify_one() mit dem Warten begonnen hat.

Der benachrichtigende Thread muss die Sperre nicht auf demselben Mutex halten wie der/die wartenden Thread(s); Tatsächlich ist dies eine Pessimierung, da der benachrichtigte Thread sofort wieder blockieren würde, während er darauf wartet, dass der benachrichtigende Thread die Sperre freigibt. Einige Implementierungen (insbesondere viele Implementierungen von pthreads) erkennen jedoch diese Situation und vermeiden dieses "Hurry up and wait"-Szenario, indem sie den wartenden Thread während des Notify-Aufrufs direkt von der Warteschlange der Condition Variable in die Warteschlange des Mutex transferieren, ohne ihn aufzuwecken.

Das Benachrichtigen unter Sperre kann dennoch notwendig sein, wenn eine präzise Planung von Ereignissen erforderlich ist, z.B. wenn der wartende Thread das Programm beenden würde, falls die Bedingung erfüllt ist, was zur Zerstörung der Condition Variable des benachrichtigenden Threads führt. Ein falsches Aufwachen nach dem Entsperren des Mutex, aber vor der Benachrichtigung, würde dazu führen, dass die Benachrichtigung auf einem zerstörten Objekt aufgerufen wird.

Beispiel

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
using namespace std::chrono_literals;
std::condition_variable 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();
}

Mögliche Ausgabe:

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

Siehe auch

benachrichtigt alle wartenden Threads
(öffentliche Mitgliedsfunktion)
C-Dokumentation für cnd_signal