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
Definido en el encabezado <condition_variable>
class condition_variable ;
(desde C++11)

std::condition_variable es una primitiva de sincronización utilizada con un std::mutex para bloquear uno o más hilos hasta que otro hilo modifique una variable compartida (la condición ) y notifique al std::condition_variable .

El hilo que pretende modificar la variable compartida debe:

  1. Adquirir un std::mutex (típicamente mediante std::lock_guard ).
  2. Modificar la variable compartida mientras se posee el bloqueo.
  3. Llamar a notify_one o notify_all en el std::condition_variable (puede realizarse después de liberar el bloqueo).

Aunque la variable compartida sea atómica, debe modificarse mientras se posee el mutex para publicar correctamente la modificación al hilo en espera.

Cualquier hilo que pretenda esperar en una std::condition_variable debe:

  1. Adquiera un std:: unique_lock < std:: mutex > en el mutex utilizado para proteger la variable compartida.
  2. Realice una de las siguientes acciones:
  1. Verificar la condición, en caso de que ya haya sido actualizada y notificada.
  2. Llamar wait , wait_for , o wait_until en el std::condition_variable (libera atómicamente el mutex y suspende la ejecución del hilo hasta que la variable de condición sea notificada, expire un tiempo de espera, o ocurra un spurious wakeup , luego adquiere atómicamente el mutex antes de retornar).
  3. Verificar la condición y reanudar la espera si no está satisfecha.
o:
  1. Usar la sobrecarga con predicado de wait , wait_for , y wait_until , que realiza los mismos tres pasos.

std::condition_variable funciona únicamente con std:: unique_lock < std:: mutex > , lo que permite la máxima eficiencia en algunas plataformas. std::condition_variable_any proporciona una variable de condición que funciona con cualquier objeto BasicLockable , como std::shared_lock .

Las variables de condición permiten la invocación concurrente de las funciones miembro wait , wait_for , wait_until , notify_one y notify_all .

La clase std::condition_variable es un StandardLayoutType . No es CopyConstructible , MoveConstructible , CopyAssignable , ni MoveAssignable .

Contenidos

Tipos anidados

Nombre Definición
native_handle_type definido por la implementación

Funciones miembro

construye el objeto
(función miembro pública)
destruye el objeto
(función miembro pública)
operator=
[deleted]
no asignable por copia
(función miembro pública)
Notificación
notifica un hilo en espera
(función miembro pública)
notifica todos los hilos en espera
(función miembro pública)
Espera
bloquea el hilo actual hasta que la variable de condición sea despertada
(función miembro pública)
bloquea el hilo actual hasta que la variable de condición sea despertada o después de la duración de tiempo de espera especificada
(función miembro pública)
bloquea el hilo actual hasta que la variable de condición sea despertada o hasta que se alcance el punto de tiempo especificado
(función miembro pública)
Manejador nativo
devuelve el manejador nativo
(función miembro pública)

Ejemplo

std::condition_variable se utiliza en combinación con un std::mutex para facilitar la comunicación entre hilos.

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

Salida:

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

Véase también

proporciona una variable de condición asociada con cualquier tipo de bloqueo
(clase)
(C++11)
proporciona funcionalidad básica de exclusión mutua
(clase)
(C++11)
implementa un contenedor de propiedad de mutex estrictamente basado en ámbito
(plantilla de clase)
implementa un contenedor de propiedad de mutex movible
(plantilla de clase)