Espacios de nombres
Variantes
Acciones

Diferencia entre revisiones de «cpp/thread/condition variable»

De cppreference.com
< cpp‎ | thread
m (Allow search engines to index popular pages.)
m (actualización)
 
Línea 1: Línea 1:
{{tr note|index}}
 
 
{{cpp/title|condition_variable}}
 
{{cpp/title|condition_variable}}
 
{{cpp/thread/condition_variable/navbar}}
 
{{cpp/thread/condition_variable/navbar}}
{{ddcl | header=condition_variable | notes={{mark since c++11}} | 1=
+
{{ddcl | header=condition_variable | sincec++11 | 1=
 
class condition_variable;
 
class condition_variable;
 
}}
 
}}
  
{{tr|La clase {{tt|condition_variable}} es una primitiva de sincronización que se puede utilizar para bloquear un hilo, o hilos de múltiples al mismo tiempo, hasta que:|The {{tt|condition_variable}} class is a synchronization primitive that can be used to block a thread, or multiple threads at the same time, until:}}
+
La clase {{tt|condition_variable}} es una primitiva de sincronización que se puede para bloquear un hilo, o hilos al mismo tiempo, hasta que {{tt|condition_variable}}
  
* {{tr|se recibe una notificación de otro hilo|a notification is received from another thread}}
+
* {{tr|un tiempo de espera, o|a timeout expires, or}}
+
{{||}}
* {{tr|un [[enwiki:Spurious_wakeup|activación espuria]] se produce|a [[enwiki:Spurious_wakeup|activación espuria]] occurs}}
+
 +
{{|o |}} {{|::}}
 +
  
{{tr|Cualquier hilo que tiene la intención de esperar en {{tt|std::condition_variable}} tiene que adquirir un {{lc|std::unique_lock}} primero. Las operaciones de espera atómicamente liberar la exclusión mutua y la suspensión de la ejecución de la rosca. Cuando la variable de estado se notifica, el hilo se despertó y volvió a adquirir el mutex está .|Any thread that intends to wait on {{tt|std::condition_variable}} has to acquire a {{lc|std::unique_lock}} first. The wait operations atomically release the mutex and suspend the execution of the thread. When the condition variable is notified, the thread is awakened, and the mutex is reacquired.}}
+
Cualquier hilo que tiene la intención de esperar en {{tt|std::condition_variable}}
 +
un {{|std::unique_lock
 +
 +
 +
}}. Las operaciones de espera atómicamente y la ejecución .
 +
la variable de , el hilo se y a mutex.
 +
 +
{{tt|}}{{lc|}}, , }}
  
{{tr|La clase es un {{tt|std::condition_variable}} {{concept|StandardLayoutType}}. No es {{concept|CopyConstructible}}, {{concept|MoveConstructible}}, {{concept|CopyAssignable}}, {{concept|MoveAssignable}} .|The class {{tt|std::condition_variable}} is a {{concept|StandardLayoutType}}. It is not {{concept|CopyConstructible}}, {{concept|MoveConstructible}}, {{concept|CopyAssignable}}, {{concept|MoveAssignable}}.}}
+
{{tt|std::condition_variable}} {{|}}. {{|}} {{|}}, {{|std::}}.
  
===Tipos de miembros===
+
 +
 
 +
 +
 
 +
===Tipos ===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc hitem |{{tr| Miembro de tipo | Member type }}| Definition}}
+
{{dsc hitem | | }}
{{dsc | {{tt|native_handle_type}} |{{tr| '''' Definido por la implantación| ''implementation-defined''}}}}
+
{{dsc | {{tt|native_handle_type}} | ''por la ''}}
 
{{dsc end}}
 
{{dsc end}}
  
===Las funciones miembro===
+
===miembro===
 
{{dsc begin}}
 
{{dsc begin}}
 
{{dsc inc | cpp/thread/condition_variable/dsc constructor | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc constructor | condition_variable}}
Línea 28: Línea 40:
 
{{dsc inc | cpp/thread/condition_variable/dsc operator{{=}} | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc operator{{=}} | condition_variable}}
  
{{dsc h2 |{{tr| Notificación| Notification}}}}
+
{{dsc h2 | Notificación}}
 
{{dsc inc | cpp/thread/condition_variable/dsc notify_one | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc notify_one | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc notify_all | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc notify_all | condition_variable}}
  
{{dsc h2 |{{tr| Espera| Waiting}}}}
+
{{dsc h2 | Espera}}
 
{{dsc inc | cpp/thread/condition_variable/dsc wait | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc wait | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc wait_for | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc wait_for | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc wait_until | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc wait_until | condition_variable}}
  
{{dsc h2 |{{tr| Identificador nativo| Native handle}}}}
+
{{dsc h2 | Identificador nativo}}
 
{{dsc inc | cpp/thread/condition_variable/dsc native handle | condition_variable}}
 
{{dsc inc | cpp/thread/condition_variable/dsc native handle | condition_variable}}
 
{{dsc end}}
 
{{dsc end}}
  
 
===Ejemplo===
 
===Ejemplo===
{{example
+
{{example| |
|
+
|code=
| p=true
+
| code=
+
#include <condition_variable>
+
#include <mutex>
+
#include <thread>
+
 
#include <iostream>
 
#include <iostream>
#include <queue>
+
#include <>
#include <chrono>
+
#include <
 +
 +
>
  
int main()
+
 +
 +
 +
 +
 +
 
 +
()
 
{
 
{
     std::queue<int> produced_nums;
+
    std::mutex m;
+
     std::<std::mutexm;
     std::condition_variable cond_var;
+
     ;;
    bool done = false;
+
    bool notified = false;
+
  
     std::thread producer([&]() {
+
        for (int i = 0; i < 5; ++i) {
+
     std::
            std::this_thread::sleep_for(std::chrono::seconds(1));
+
= ;
            std::unique_lock<std::mutex> lock(m);
+
 
            std::cout << "producing " << i << '\n';
+
()
            produced_nums.push(i);
+
;
            notified = true;
+
std::cout << "\n;
            cond_var.notify_one();
+
        }  
+
 +
 +
.();
 +
.notify_one();
 +
}
 +
 
 +
 +
 +
  
         done = true;
+
         cond_var.notify_one();
+
     });  
+
 +
 +
         = true;
 +
         () ;
 +
     }
 +
);
  
     std::thread consumer([&]() {
+
    
         std::unique_lock<std::mutex> lock(m);
+
{
         while (!done) {
+
         std::unique_lock<std::mutex> (m);
            while (!notified) {  // loop to avoid spurious wakeups
+
         .wait();
                cond_var.wait(lock);
+
}
            }  
+
std::cout << "" << << '\n';
            while (!produced_nums.empty()) {
+
                std::cout << "consuming " << produced_nums.front() << '\n';
+
                produced_nums.pop();
+
            } 
+
            notified = false;
+
        } 
+
    });  
+
  
     producer.join();
+
     .join();
    consumer.join();
+
 
}
 
}
| output=
+
| output=
producing 0
+
consuming 0
+
producing 1
+
consuming 1
+
producing 2
+
consuming 2
+
producing 3
+
consuming 3
+
producing 4
+
consuming 4
+
 
}}
 
}}
  
[[de:cpp/thread/condition variable]]
+
deenfritjaptruzh
[[en:cpp/thread/condition variable]]
+
[[fr:cpp/thread/condition variable]]
+
[[it:cpp/thread/condition variable]]
+
[[ja:cpp/thread/condition variable]]
+
[[pt:cpp/thread/condition variable]]
+
[[ru:cpp/thread/condition variable]]
+
[[zh:cpp/thread/condition variable]]
+

Última revisión de 13:24 3 sep 2021

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

La clase condition_variable es una primitiva de sincronización que se puede usar para bloquear un hilo, o varios hilos al mismo tiempo, hasta que otro hilo modifique una variable compartida (la condición) y notifique a la variable de condición, condition_variable.

El hilo que pretende modificar la variable compartida debe:

  1. tomar posesión de un std::mutex (típicamente mediante std::lock_guard);
  2. realizar la modificación mientras se mantiene el bloqueo;
  3. ejecutar notify_one o notify_all en la variable de condición, std::condition_variable (no necesita mantenerse el bloqueo para la notificación).

Incluso si la variable compartida es atómica, debe modificarse bajo el mutex para publicar correctamente la modificación en el hilo en espera.

Cualquier hilo que tiene la intención de esperar en std::condition_variable debe:

  1. tomar posesión de un std::unique_lock<std::mutex>, en el mismo mutex que se usó para proteger la variable compartida;
  2. ya sea:
  1. verificar la condición, en caso de que ya haya sido actualizada y notificada;
  2. ejecutar wait, wait_for, o wait_until. Las operaciones de espera liberan atómicamente el mutex y suspenden la ejecución del hilo.
  3. cuando se notifica a la variable de condición, expira un tiempo de espera o se produce un despertar espurio o falso el hilo se despierta y se vuelve a tomar posesión del mutex atómicamente; luego el hilo debe verificar la condición y continuar esperando si el despertar fue falso.
o:
  1. usar la sobrecarga que toma un predicado (parámetro de plantilla Predicate) de wait, wait_for, y wait_until, que se encarga de los tres pasos anteriores.

std::condition_variable solamente funciona con std::unique_lock<std::mutex>; esta restricción 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 simultánea de las funciones miembro wait, wait_for, wait_until, notify_one y notify_all.

La clase std::condition_variable cumple con los requerimientos de StandardLayoutType. No es CopyConstructible, MoveConstructible, CopyAssignable, o MoveAssignable.

Contenido

[editar] Tipos miembro

Tipo miembro Definición
native_handle_type definido por la implementación

[editar] Funciones miembro

Construye el objeto.
(función miembro pública) [editar]
Destruye el objeto.
(función miembro pública) [editar]
operator=
[eliminada]
No es asignable mediante copia.
(función miembro pública) [editar]
Notificación
Notifica a un hilo en espera.
(función miembro pública) [editar]
Notifica a todos los hilos en espera.
(función miembro pública) [editar]
Espera
Bloquea el hilo actual hasta que la variable de condición se despierte.
(función miembro pública) [editar]
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]
Identificador nativo
Devuelve el identificador nativo.
(función miembro pública) [editar]

[editar] Ejemplo

condition_variable se usa en combinación con un std::mutex para facilitar la comunicación intrahilos.

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
 
std::mutex m;
std::condition_variable cv;
std::string datos;
bool listo = false;
bool procesados = false;
 
void hilo_obrero()
{
    // Esperar hasta que main() mande datos
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{return listo;});
 
    // después de la espera, tenemos posesión del cerrojo.
    std::cout << "Hilo obrero procesando datos\n";
    datos += " después de procesar";
 
    // Enviar datos de vuelta a main()
    procesados = true;
    std::cout << "Hilo obrero indica procesamiento de datos completo\n";
 
    // Se hace un desbloqueo manual antes de notificar, para evitar despertar
    // el hilo en espera solo para bloquearse de nuevo (véase notify_one para detalles)
    lk.unlock();
    cv.notify_one();
}
 
int main()
{
    std::thread obrero(hilo_obrero);
 
    datos = "Datos de ejemplo";
    // enviar datos al hilo obrero
    {
        std::lock_guard<std::mutex> lk(m);
        listo = true;
        std::cout << "main() indica datos listos para procesar\n";
    }
    cv.notify_one();
 
    // esperar al hilo obrero
    {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{return procesados;});
    }
    std::cout << "De vuelta en main(), datos = " << datos << '\n';
 
    obrero.join();
}

Salida:

main() indica datos listos para procesar
Hilo obrero procesando datos
Hilo obrero indica procesamiento de datos completo
De vuelta en main(), datos = Datos de ejemplo después de procesar