std::condition_variable_any:: notify_one
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Notification | ||||
|
condition_variable_any::notify_one
|
||||
| Waiting | ||||
|
void
notify_one
(
)
noexcept
;
|
(desde C++11) | |
Si algún hilo está esperando en
*
this
, llamar a
notify_one
desbloquea uno de los hilos en espera.
Notas
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()
.
El hilo que notifica no necesita mantener el bloqueo sobre el mismo mutex que el mantenido por el(los) hilo(s) en espera; de hecho, hacerlo es una pessimización, ya que el hilo notificado bloquearía inmediatamente otra vez, esperando a que el hilo notificador libere el bloqueo. Sin embargo, algunas implementaciones (en particular muchas implementaciones de pthreads) reconocen esta situación y evitan este escenario de "apresurarse y esperar" transfiriendo el hilo en espera de la cola de la variable de condición directamente a la cola del mutex dentro de la llamada de notificación, sin despertarlo.
Notificar mientras se mantiene el bloqueo puede ser necesario cuando se requiere una programación precisa de eventos, por ejemplo, si el hilo en espera saldría del programa si se satisface la condición, causando la destrucción de la variable de condición del hilo que notifica. Un despertar espurio después de desbloquear el mutex pero antes de la notificación resultaría en una notificación llamada sobre un objeto destruido.
Ejemplo
#include <chrono> #include <condition_variable> #include <iostream> #include <thread> using namespace std::chrono_literals; std::condition_variable_any cv; std::mutex cv_m; int i = 0; bool done = false; void waits() { std::unique_lock<std::mutex> lk(cv_m); std::cout << "Waiting... \n"; cv.wait(lk, []{ return i == 1; }); std::cout << "...finished waiting; i == " << i << '\n'; done = true; } void signals() { std::this_thread::sleep_for(200ms); std::cout << "Notifying falsely...\n"; cv.notify_one(); // waiting thread is notified with i == 0. // cv.wait wakes up, checks i, and goes back to waiting std::unique_lock<std::mutex> lk(cv_m); i = 1; while (!done) { std::cout << "Notifying true change...\n"; lk.unlock(); cv.notify_one(); // waiting thread is notified with i == 1, cv.wait returns std::this_thread::sleep_for(300ms); lk.lock(); } } int main() { std::thread t1(waits), t2(signals); t1.join(); t2.join(); }
Salida posible:
Waiting... Notifying falsely... Notifying true change... ...finished waiting; i == 1
Véase también
|
notifica a todos los hilos en espera
(función miembro pública) |
|
|
C documentation
para
cnd_signal
|
|