Namespaces
Variants

std::condition_variable:: wait_for

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
template < class Rep, class Period >

std:: cv_status wait_for ( std:: unique_lock < std:: mutex > & lock,

const std:: chrono :: duration < Rep, Period > & rel_time ) ;
(1) (seit C++11)
template < class Rep, class Period, class Predicate >

bool wait_for ( std:: unique_lock < std:: mutex > & lock,
const std:: chrono :: duration < Rep, Period > & rel_time,

Predicate pred ) ;
(2) (seit C++11)

wait_for bewirkt, dass der aktuelle Thread blockiert, bis die Bedingungsvariable benachrichtigt wird, die angegebene Dauer abgelaufen ist oder ein spontanes Aufwachen auftritt. pred kann optional bereitgestellt werden, um spontanes Aufwachen zu erkennen.

1) Entspricht return wait_until ( lock, std:: chrono :: steady_clock :: now ( ) + rel_time ) ; .
2) Entspricht return wait_until ( lock, std:: chrono :: steady_clock :: now ( ) + rel_time, std :: move ( pred ) ) ; .
Diese Überladung kann verwendet werden, um falsche Aufweckvorgänge zu ignorieren, während auf das Eintreten einer bestimmten Bedingung gewartet wird.

Unmittelbar nachdem wait_for zurückkehrt, ist lock. owns_lock ( ) true , und lock. mutex ( ) wird vom aufrufenden Thread gesperrt. Wenn diese Nachbedingungen nicht erfüllt werden können [1] , ruft es std::terminate auf.

Wenn eine der folgenden Bedingungen erfüllt ist, ist das Verhalten undefiniert:

  • lock. owns_lock ( ) ist false .
  • lock. mutex ( ) ist nicht durch den aufrufenden Thread gesperrt.
  • Falls andere Threads ebenfalls auf * this warten, unterscheidet sich lock. mutex ( ) von dem Mutex, der durch die Wartefunktionen ( wait , wait_for und wait_until ) auf * this durch jene Threads entsperrt wird.
  1. Dies kann passieren, wenn das erneute Sperren des Mutex eine Exception auslöst.

Inhaltsverzeichnis

Parameter

lock - eine Sperre, die vom aufrufenden Thread gesperrt werden muss
rel_time - die maximale Wartezeit
pred - das Prädikat zur Überprüfung, ob das Warten abgeschlossen werden kann
Typanforderungen
-
Predicate muss die Anforderungen von FunctionObject erfüllen.
-
pred ( ) muss ein gültiger Ausdruck sein, und sein Typ und Wertkategorie müssen die BooleanTestable Anforderungen erfüllen.

Rückgabewert

1) std:: cv_status :: timeout falls rel_time seit Beginn dieses Aufrufs verstrichen ist, andernfalls std:: cv_status :: no_timeout .
2) Das letzte Ergebnis von pred ( ) vor der Rückkehr zum Aufrufer.

Ausnahmen

1) Zeitüberschreitungsbezogene Ausnahmen.
2) Zeitüberschreitungsbezogene Ausnahmen und alle Ausnahmen, die von pred ausgelöst werden.

Hinweise

Selbst wenn unter Sperre benachrichtigt, gibt Overload (1) keine Garantien über den Zustand des zugehörigen Prädikats bei Rückkehr aufgrund von Timeout.

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

Beispiel

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
std::condition_variable cv;
std::mutex cv_m; // Dieses Mutex wird für drei Zwecke verwendet:
                 // 1) zum Synchronisieren von Zugriffen auf i
                 // 2) zum Synchronisieren von Zugriffen auf std::cerr
                 // 3) für die Condition Variable cv
int i = 0;
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "Waiting... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cerr << "...finished waiting. i == 1\n";
}
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Notifying...\n";
    }
    cv.notify_all();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        i = 1;
        std::cerr << "Notifying again...\n";
    }
    cv.notify_all();
}
int main()
{
    std::thread t1(waits), t2(waits), t3(waits), t4(signals);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

Mögliche Ausgabe:

Waiting...
Waiting...
Waiting...
Notifying...
Notifying again...
...finished waiting. i == 1
...finished waiting. i == 1
...finished waiting. i == 1

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 2093 C++11 Timeout-bezogene Ausnahmen fehlten in der Spezifikation erwähnt diese Ausnahmen
LWG 2114
( P2167R3 )
C++11 Konvertierbarkeit zu bool war zu schwach, um die Erwartungen der Implementierungen widerzuspiegeln Anforderungen verstärkt
LWG 2135 C++11 das Verhalten war unklar, wenn lock. lock ( ) eine Ausnahme wirft ruft std::terminate in diesem Fall auf

Siehe auch

blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird
(public member function)
blockiert den aktuellen Thread, bis die Condition Variable aufgeweckt wird oder der angegebene Zeitpunkt erreicht ist
(public member function)