std::condition_variable_any::wait_for
template<class Lock, class Rep, class Period > std::cv_status wait_for( Lock& lock, | (1) | (desde C++11) |
template<class Lock, class Rep, class Period, class Predicate > bool wait_for( Lock& lock, | (2) | (desde C++11) |
template<class Lock, class Rep, class Period, class Predicate > bool wait_for( Lock& lock, | (3) | (desde C++20) |
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(), o cuando el tiempo de espera relativo rel_time
expire. También se puede desbloquear de forma espuria. Cuando se desbloquea, independientemente del motivo, se vuelve a tomar posesión de lock
y wait_for()
sale.El estándar recomienda que se utilice un reloj fijo para medir la duración. Esta función puede bloquearse por más de timeout_duration
debido a demoras en la programación o en la contención de recursos.
Si estas funciones no cumplen con la poscondición (lock 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 Lock que cumple con los requerimientos de BasicLockable, que debe estar bloqueado por el hilo actual. |
stoken | - | Un símbolo de detención std::stop_token para el cual registrar la interrupción. |
rel_time | - | Un objeto de tipo std::chrono::duration que representa el tiempo máximo de espera. Ten en cuenta que rel_time debe ser lo suficientemente pequeño como para no desbordarse cuando se agrega a std::chrono::steady_clock::now(). |
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
rel_time
expiró, std::cv_status::no_timeout de lo contrario.pred
todavía se evalúa a false después de que el tiempo de espera rel_time
expiró, true de lo contrario.[editar]Excepciones
pred
.[editar]Notas
Incluso si se notifica bajo bloqueo, la sobrecarga (1) no garantiza el estado del predicado asociado cuando regresa debido al tiempo de espera.
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 <atomic>#include <condition_variable>#include <thread>#include <chrono>usingnamespace std::chrono_literals; std::condition_variable_any cv;std::mutex cv_m;int i; void espera(int idx){std::unique_lock<std::mutex> lk(cv_m);if(cv.wait_for(lk, idx*100ms, []{return i ==1;}))std::cerr<<"Hilo "<< idx <<" ha terminado la espera. i == "<< i <<'\n';elsestd::cerr<<"Hilo "<< idx <<" agotado. i == "<< i <<'\n';} void indica(){std::this_thread::sleep_for(120ms);std::cerr<<"Notificando...\n"; cv.notify_all();std::this_thread::sleep_for(100ms);{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, 1), t2(espera, 2), t3(espera, 3), t4(indica); t1.join(); t2.join(); t3.join(); t4.join();}
Salida:
Hilo 1 agotado. i == 0 Notificando... Hilo 2 agotado. i == 0 Notificando de nuevo... Hilo 3 ha terminado 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 2093 | C++11 | Faltaban excepciones relacionadas con el tiempo de espera en la especificación. | Se mencionan. |
LWG 2135 | C++11 | wait_for 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. (función miembro pública) | |
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) |