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
Definiert im Header <condition_variable>
class condition_variable ;
(seit C++11)

std::condition_variable ist ein Synchronisierungsprimitive, das zusammen mit einem std::mutex verwendet wird, um einen oder mehrere Threads zu blockieren, bis ein anderer Thread sowohl eine gemeinsame Variable (die Bedingung ) ändert als auch die std::condition_variable benachrichtigt.

Der Thread, der die gemeinsame Variable ändern möchte, muss:

  1. Erwerben Sie einen std::mutex (typischerweise über std::lock_guard ).
  2. Modifizieren Sie die gemeinsame Variable, während die Sperre gehalten wird.
  3. Rufen Sie notify_one oder notify_all auf der std::condition_variable auf (kann nach dem Freigeben der Sperre erfolgen).

Selbst wenn die gemeinsam genutzte Variable atomar ist, muss sie unter Besitz des Mutex geändert werden, um korrekt die Änderung an den wartenden Thread zu publizieren.

Jeder Thread, der auf eine std::condition_variable warten möchte, muss:

  1. Erwerben Sie einen std:: unique_lock < std:: mutex > für den Mutex, der zum Schutz der gemeinsamen Variable verwendet wird.
  2. Führen Sie eines der folgenden aus:
  1. Überprüfen Sie die Bedingung, falls sie bereits aktualisiert und benachrichtigt wurde.
  2. Rufen Sie wait , wait_for oder wait_until auf dem std::condition_variable auf (gibt das Mutex atomar frei und unterbricht die Thread-Ausführung, bis die Bedingungsvariable benachrichtigt wird, ein Timeout abläuft oder ein spurious wakeup auftritt, und erwirbt dann atomar das Mutex vor der Rückgabe).
  3. Überprüfen Sie die Bedingung und setzen Sie das Warten fort, falls nicht erfüllt.
oder:
  1. Verwenden Sie die überladene Version mit Prädikat von wait , wait_for und wait_until , die dieselben drei Schritte ausführt.

std::condition_variable funktioniert nur mit std:: unique_lock < std:: mutex > , was auf einigen Plattformen maximale Effizienz ermöglicht. std::condition_variable_any bietet eine Condition Variable, die mit jedem BasicLockable -Objekt funktioniert, wie beispielsweise std::shared_lock .

Condition-Variablen ermöglichen die gleichzeitige Ausführung der wait -, wait_for -, wait_until -, notify_one - und notify_all -Memberfunktionen.

Die Klasse std::condition_variable ist ein StandardLayoutType . Sie ist weder CopyConstructible , MoveConstructible , CopyAssignable noch MoveAssignable .

Inhaltsverzeichnis

Verschachtelte Typen

Name Definition
native_handle_type implementation-defined

Memberfunktionen

Konstruiert das Objekt
(öffentliche Elementfunktion)
Destruiert das Objekt
(öffentliche Elementfunktion)
operator=
[deleted]
nicht kopierzuweisbar
(öffentliche Elementfunktion)
Benachrichtigung
benachrichtigt einen wartenden Thread
(öffentliche Elementfunktion)
benachrichtigt alle wartenden Threads
(öffentliche Elementfunktion)
Warten
blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird
(öffentliche Elementfunktion)
blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird oder nach Ablauf der angegebenen Timeout-Dauer
(öffentliche Elementfunktion)
blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird oder bis der angegebene Zeitpunkt erreicht wurde
(öffentliche Elementfunktion)
Native Handle
gibt das native Handle zurück
(öffentliche Elementfunktion)

Beispiel

std::condition_variable wird in Kombination mit einem std::mutex verwendet, um die Kommunikation zwischen Threads zu ermöglichen.

#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();
}

Ausgabe:

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

Siehe auch

stellt eine Bedingungsvariable bereit, die mit jedem Sperrtyp assoziiert werden kann
(Klasse)
(C++11)
bietet grundlegende gegenseitige Ausschlussfunktionalität
(Klasse)
(C++11)
implementiert einen streng bereichsbasierten Mutex-Eigentums-Wrapper
(Klassentemplate)
implementiert einen beweglichen Mutex-Eigentums-Wrapper
(Klassentemplate)