¿Hay algún problema con este uso del código de condición de refuerzo?
-
06-07-2019 - |
Pregunta
¿Este código esperará alguna vez en el mutex dentro del void push (data)
del productor
Si es así, ¿cómo puedo evitar eso?
boost::mutex access;
boost::condition cond;
// consumer
data read()
{
boost::mutex::scoped_lock lock(access);
// this blocks until the data is ready
cond.wait(lock);
// queue is ready
return data_from_queue();
}
// producer
void push(data)
{
//<--- will a block ever happen here?
boost::mutex::scoped_lock lock(access);
// add data to queue
cond.notify_one();
}
Digamos que tengo un grupo de subprocesos para el bucle (;;) y he leído () que se llama desde un subproceso en este grupo. Luego proceso datos sobre él. Y llamo a push () con un hilo externo. Mi pregunta es, ¿puede ese hilo externo bloquear alguna vez su llamada a empujar (datos)?
Solución
Cuando se llama a .wait (), bloqueará el hilo de llamada en su grupo de hilos y liberará el mutex. Volverá cuando alguien llame a notify_one () o notify_all (). Sin embargo, antes de que el hilo bloqueado regrese, volverá a adquirir el mutex y desbloqueará el hilo en su grupo de hilos.
Entonces, la llamada a void push (data)
por su hilo externo solo se bloqueará temporalmente hasta que se llame a .wait ().
Consulte la documentación de impulso sobre la función de espera de la condición .
Otros consejos
wait
puede regresar sin que nunca se llame a notifique
. Esto se denomina espuria wakeup . Para manejar esto, el código que usa una condición siempre debe tener un bucle alrededor del wait
que verifica que la condición esperada realmente esté vigente. Por ejemplo:
queue data_queue;
boost::mutex access;
boost::condition cond;
// consumer
data read()
{
boost::mutex::scoped_lock lock(access);
while (queue.is_empty()) {
// this blocks until the data is ready
cond.wait(lock);
}
// queue is ready
return data_from_queue();
}
// producer
void push(data)
{
boost::mutex::scoped_lock lock(access);
// add data to queue
queue.push_back(data);
cond.notify_one();
}
Conceptualmente, "condición" Es un poco engañoso. En cambio, puedes pensar en ello como una señal. Está indicando a otro hilo o hilos que se despierten, pero no promete nada. Simplemente, "Hey, tal vez hay algunos datos listos, ¿por qué no vas a comprobar eh?