¿Cuál es la diferencia entre notificar_todos() y notificar_uno() de std::condition_variable?

2 minutos de lectura

avatar de usuario
yunhuang

Actualmente, estoy implementando un proyecto de subprocesos múltiples usando std::thread en C++11. yo suelo std::condition_variable para sincronizar hilos. En detalle, una función de consumidor llama wait() función miembro de std::condition_variable para esperar una tarea de una cola de tareas global, otra función de productor genera y coloca tareas en la cola. Pero no sé la diferencia entre notify_all() y notify_one() funciones de miembro de std::condition_variable. ¿Qué función debo usar en la función de productor? ¡Gracias!

Si hay diez subprocesos bloqueados en la variable de condición, por ejemplo, notify_one() desbloqueará solo un hilo, mientras que notify_all() los desbloqueará a todos. En tu caso, querrás usar notify_one() para que no despiertes subprocesos que no tienen ningún trabajo esperándolos.

  • Gracias, GMan. Leí algunos documentos de Internet. Justo como lo que dijiste. Sin embargo, normalmente la función wait() se usa en un mutex, por ejemplo, std::unique_lock<:mutex> ul(m_mutexTask); while (m_lTask.empty()) { m_condTask.wait(ul); } . Entonces, incluso notificar_todos() activa todos los subprocesos, solo hay un subproceso que podría bloquear el mutex, ¿verdad?

    -Yun Huang

    26 de enero de 2012 a las 9:14


  • Solo un subproceso bloqueará el mutex a la vez, pero todos regresarán del wait tan pronto como obtengan el mutex.

    –David Schwartz

    26 de enero de 2012 a las 9:23


  • @Yun: Cuál usar depende realmente de si alguno de los subprocesos en espera puede manejar lo que se está esperando. Si alguno funciona (p. ej., múltiples lectores idénticos en una cola), entonces use notificar_uno ya que definitivamente es más eficiente. Si hay una condición más compleja en la que solo un subproceso en espera podría realmente tener éxito con la condición de bucle, debe activarlos a todos, ya que no puede controlar qué subproceso despertará mediante la notificación_uno.

    – Becarios Donal

    26 de enero de 2012 a las 9:37

  • Y si solo hay un hilo en espera, entonces no importa cuál use. Así que también podrías usar notify_all en caso de que alguna vez agregue más esperas en el futuro, dado que las esperas en una variable de condición pueden activarse sin motivo, y deben escribirse para manejar eso correctamente, agregar activaciones adicionales no daña más que quizás el rendimiento. Mientras que si usas notify_one, es posible que accidentalmente escriba código que dependa de la elección del subproceso “correcto”. Puede parecer que funciona y pasa todas las pruebas, pero luego, algún cambio sutil en el futuro hace que deje de funcionar.

    –Steve Jessop

    26 de enero de 2012 a las 9:48


¿Ha sido útil esta solución?