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) (desde 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) (desde C++11)

wait_for hace que el hilo actual se bloquee hasta que la variable de condición sea notificada, haya transcurrido la duración dada, o ocurra un despertar espurio. pred puede proporcionarse opcionalmente para detectar despertar espurio.

1) Equivalente a return wait_until ( lock, std:: chrono :: steady_clock :: now ( ) + rel_time ) ; .
2) Equivalente a return wait_until ( lock, std:: chrono :: steady_clock :: now ( ) + rel_time, std :: move ( pred ) ) ; .
Esta sobrecarga puede utilizarse para ignorar despertares espurios mientras se espera que una condición específica se vuelva verdadera.

Inmediatamente después de que wait_for retorne, lock. owns_lock ( ) es true , y lock. mutex ( ) está bloqueado por el hilo que realiza la llamada. Si estas postcondiciones no pueden satisfacerse [1] , se llama a std::terminate .

Si se satisface cualquiera de las siguientes condiciones, el comportamiento es indefinido:

  • lock. owns_lock ( ) es false .
  • lock. mutex ( ) no está bloqueado por el hilo que realiza la llamada.
  • Si otros hilos también están esperando en * this , lock. mutex ( ) es diferente del mutex desbloqueado por las funciones de espera ( wait , wait_for y wait_until ) llamadas en * this por esos hilos.
  1. Esto puede ocurrir si el re-bloqueo del mutex lanza una excepción.

Contenidos

Parámetros

lock - un candado que debe ser bloqueado por el hilo que realiza la llamada
rel_time - la duración máxima de espera
pred - el predicado para verificar si la espera puede completarse
Requisitos de tipo
-
Predicate debe cumplir con los requisitos de FunctionObject .
-
pred ( ) debe ser una expresión válida, y su tipo y categoría de valor deben cumplir con los BooleanTestable requisitos.

Valor de retorno

1) std:: cv_status :: timeout si rel_time ha transcurrido desde el inicio de esta llamada, de lo contrario std:: cv_status :: no_timeout .
2) El resultado más reciente de pred ( ) antes de retornar al llamador.

Excepciones

1) Excepciones relacionadas con el tiempo de espera.
2) Excepciones relacionadas con el tiempo de espera, y cualquier excepción lanzada por pred .

Notas

Aunque se notifique bajo bloqueo, la sobrecarga (1) no ofrece garantías sobre el estado del predicado asociado al retornar por tiempo de espera agotado.

Los efectos de notify_one() / notify_all() y cada una de las tres partes atómicas de wait() / wait_for() / wait_until() (desbloquear+espera, despertar y bloquear) ocurren en un único orden total que puede verse como el orden de modificación de una variable atómica: el orden es específico de esta variable de condición individual. Esto hace imposible que notify_one() pueda, por ejemplo, retrasarse y desbloquear un hilo que comenzó a esperar justo después de que se realizó la llamada a notify_one() .

Ejemplo

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
std::condition_variable cv;
std::mutex cv_m; // Este mutex se utiliza para tres propósitos:
                 // 1) sincronizar accesos a i
                 // 2) sincronizar accesos a std::cerr
                 // 3) para la variable de condición 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();
}

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2093 C++11 faltaban excepciones relacionadas con timeout en la especificación menciona estas excepciones
LWG 2114
( P2167R3 )
C++11 la convertibilidad a bool era demasiado débil para reflejar la expectativa de implementaciones requisitos fortalecidos
LWG 2135 C++11 el comportamiento no estaba claro si lock. lock ( ) lanza una excepción llama a std::terminate en este caso

Véase también

bloquea el hilo actual hasta que la variable de condición sea activada
(función miembro pública)
bloquea el hilo actual hasta que la variable de condición sea activada o hasta que se alcance el punto de tiempo especificado
(función miembro pública)