Namespaces
Variants

std::condition_variable_any:: wait_until

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 Lock, class Clock, class Duration >

std:: cv_status
wait_until ( Lock & lock,

const std:: chrono :: time_point < Clock, Duration > & abs_time ) ;
(1) (desde C++11)
template < class Lock, class Clock, class Duration, class Predicate >

bool wait_until ( Lock & lock,
const std:: chrono :: time_point < Clock, Duration > & abs_time,

Predicate pred ) ;
(2) (desde C++11)
template < class Lock, class Clock, class Duration, class Predicate >

bool wait_until ( Lock & lock, std:: stop_token stoken,
const std:: chrono :: time_point < Clock, Duration > & abs_time,

Predicate pred ) ;
(3) (desde C++20)

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

1) Llama atómicamente lock. unlock ( ) y se bloquea en * this .
El hilo se desbloqueará cuando se ejecute notify_all() o notify_one() , o cuando se alcance abs_time . También puede desbloquearse espuriamente.
Cuando se desbloquea, llama a lock. lock ( ) (posiblemente bloqueándose en el lock), luego retorna.
2,3) Esperando a que una condición específica se cumpla, puede utilizarse para ignorar activaciones espurias.
2) Equivalente a while ( ! pred ( ) )
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
return true ;
.
3) Registra * this durante la duración de esta llamada, para ser notificado si se realiza una solicitud de parada en el estado de parada asociado de stoken ; entonces es equivalente a while ( ! stoken. stop_requested ( ) )
{
if ( pred ( ) )
return true ;
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
}
return pred ( ) ;
.

Inmediatamente después de que wait_until retorne, lock está bloqueado por el hilo que realiza la llamada. Si esta postcondición no puede satisfacerse [1] , llama a std::terminate .

  1. Esto puede ocurrir si el re-bloqueo del mutex lanza una excepción.

Contenidos

Parámetros

lock - un lock que debe ser bloqueado por el hilo que realiza la llamada
stoken - un token de parada para registrar la interrupción
abs_time - el punto temporal donde expira la espera
pred - el predicado para verificar si la espera puede completarse
Requisitos de tipo
-
Lock debe cumplir con los requisitos de BasicLockable .
-
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 abs_time ha sido alcanzado, de lo contrario std:: cv_status :: no_timeout .
2,3) El resultado más reciente de pred ( ) antes de retornar al llamador.

Excepciones

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

Notas

El estándar recomienda que se utilice el reloj vinculado a abs_time para medir el tiempo; no se requiere que ese reloj sea un reloj monótono. No hay garantías respecto al comportamiento de esta función si el reloj se ajusta de manera discontinua, pero las implementaciones existentes convierten abs_time de Clock a std::chrono::system_clock y delegan en POSIX pthread_cond_timedwait para que la espera respete los ajustes del reloj del sistema, pero no los del Clock proporcionado por el usuario. En cualquier caso, la función también puede esperar más allá de cuando se haya alcanzado abs_time debido a demoras de planificación o contención de recursos.

Incluso si el reloj en uso es std::chrono::steady_clock u otro reloj monótono, un ajuste del reloj del sistema puede inducir un despertar espurio.

Los efectos de notify_one() / notify_all() y cada una de las tres partes atómicas de wait() / wait_for() / wait_until() (desbloquear+esperar, 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 realizara la llamada a notify_one() .

Ejemplo

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
std::condition_variable_any 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 << "Esperando... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cerr << "...finalizada la espera. i == 1\n";
}
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Notificando...\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 << "Notificando de nuevo...\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:

Esperando...
Esperando...
Esperando...
Notificando...
Notificando de nuevo...
...finalizada la espera. i == 1
...finalizada la espera. i == 1
...finalizada la espera. i == 1

Informes de defectos

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

DR Se aplica 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 las expectativas de las 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)
wait_until
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)