Espacios de nombres
Variantes
Acciones

std::condition_variable::wait

De cppreference.com
 
 
Biblioteca de apoyo de concurrencia
Hilos
(C++11)
(C++20)
Espacio de nombres this_thread
(C++11)
(C++11)
(C++11)
Cancelación cooperativa
Exclusión mutua
(C++11)
Gestión genérica de bloqueo
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Variables de condición
(C++11)
Semáforos
Pestillos y barreras
(C++20)
(C++20)
Futuros
(C++11)
(C++11)
(C++11)
(C++11)
Recuperación segura
(C++26)
Punteros de riesgo
Tipos atómicos
(C++11)
(C++20)
Inicialización de tipos atómicos
(C++11)(en desuso en C++20)
(C++11)(en desuso en C++20)
Orden de memoria
Funciones independientes para operaciones atómicas
Funciones independientes para indicadores atómicos
 
 
void wait( std::unique_lock<std::mutex>& lock );
(1) (desde C++11)
template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );
(2) (desde C++11)

wait hace que el hilo actual se bloquee hasta que se notifique a la variable de condición o se produzca un despertar espurio, opcionalmente en bucle hasta que se satisfaga algún predicado.

1) Desbloquea atómicamente a lock, bloquea el hilo en ejecución actual y lo agrega a la lista de hilos en espera de *this. El hilo se desbloqueará cuando se ejecute notify_all() o notify_one(). También se puede desbloquear de forma espuria. Cuando se desbloquea, independientemente del motivo, se vuelve a tomar posesión de lock y wait sale.
2) Equivalente a
while (!pred()) {
    wait(lock);
}

Esta sobrecarga se puede utilizar para ignorar los despertares espurios mientras se espera que se cumpla una condición específica.

Ten en cuenta que se debe tomar posesión de lock antes de ingresar a esta función miembro, y se vuelve a tomar posesión después de que wait(lock) sale, lo que significa que lock se puede usar para proteger el acceso a pred().


Si estas funciones no cumplen con las poscondiciones (lock.owns_lock()==true y lock.mutex() se bloquea por el hilo llamante), se llama a std::terminate. Por ejemplo, esto podría suceder si al volver a bloquear el mutex se lanza una excepción.

Contenido

[editar] Parámetros

lock - Un objeto de tipo std::unique_lock<std::mutex>, que debe estar bloqueado por el hilo actual.
pred - Predicado que devuelve ​false si la espera debería continuar..

La signatura de la función predicado deberá ser equivalente a lo siguiente:

 bool pred();

[editar] Valor de retorno

(Ninguno)

[editar] Excepciones

1) No lanza.
2) Lo mismo que (1) pero también puede propagar excepciones lanzadas por pred.


[editar] Notas

Llamar a esta función si lock.mutex() no está bloqueado por el hilo actual resulta en comportamiento no definido.

Llamar a esta función si lock.mutex() no es el mismo mutex que el usado por todos los otros hilos que se encuentran a la espera en la misma variable de condición resulta en comportamiento no definido.

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) tienen lugar en un solo orden total que se puede ver como el orden de modificación de una variable atómica: el orden es específico para esta variable de condición individual. Esto hace imposible que notify_one() por ejemplo, se retrase y desbloquee un hilo que comenzó a esperar justo después de que se hizo la llamada a notify_one().

[editar] Ejemplo

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
 
std::condition_variable cv;
std::mutex cv_m; // Se usa este mutex para tres propósitos:
                 // 1) para sincronizar accesos a i
                 // 2) para sincronizar accesos a std::cerr
                 // 3) para la variable de condición cv
int i = 0;
 
void espera()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "En espera... \n";
    cv.wait(lk, []{return i == 1;});
    std::cerr << "...terminada la espera. i == 1\n";
}
 
void indica()
{
    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(espera), t2(espera), t3(espera), t4(indica);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

Posible salida:

En espera...
En espera...
En espera...
Notificando...
Notificando de nuevo...
...terminada la espera. i == 1
...terminada la espera. i == 1
...terminada la espera. i == 1

[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 2135 C++11 wait lanzaba una excepción cuando fallaba el desbloqueo y rebloqueo. Llama a std::terminate.

[editar] Véase también

Bloquea el hilo actual hasta que la variable de condición se despierte o hasta después del tiempo de espera especificado.
(función miembro pública) [editar]
Bloquea el hilo actual hasta que la variable de condición se despierte o se haya alcanzado el punto de tiempo especificado.
(función miembro pública) [editar]
Documentación de C para cnd_wait