Llamando a la señal pthread cond sin bloquear mutex


Leí en alguna parte que deberíamos bloquear el mutex antes de llamar pthread_cond_signal y desbloquear el mutext después de llamarlo:

La rutina pthread_cond_signal () es se usa para señalar (o despertar) a otro hilo que está esperando en el variable de condición. Debería ser se llama después de que mutex está bloqueado, y debe desbloquear mutex en orden para pthread_cond_wait() rutina para completo.

Mi pregunta es: ¿no está bien llamar pthread_cond_signal o pthread_cond_broadcast métodos sin bloquear el mutex?

Author: Meysam, 2010-12-28

3 answers

Si no bloquea el mutex en la ruta de código que cambia la condición y las señales, puede perder wakeups. Considere este par de procesos:

Proceso A:

pthread_mutex_lock(&mutex);
while (condition == FALSE)
    pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

Proceso B (incorrecto):

condition = TRUE;
pthread_cond_signal(&cond);

Entonces considere esta posible intercalación de instrucciones, donde condition comienza como FALSE:

Process A                             Process B

pthread_mutex_lock(&mutex);
while (condition == FALSE)

                                      condition = TRUE;
                                      pthread_cond_signal(&cond);

pthread_cond_wait(&cond, &mutex);

El condition ahora es TRUE, pero el Proceso A está atascado esperando en la variable de condición - perdió la señal de wakeup. Si alteramos Proceso B para bloquear el mutex:

Proceso B (correcto):

pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

...entonces lo anterior no puede ocurrir; el despertar nunca se perderá.

(Tenga en cuenta que puede realmente mover el pthread_cond_signal() después del pthread_mutex_unlock(), pero esto puede resultar en una programación menos óptima de subprocesos, y necesariamente ha bloqueado el mutex ya en esta ruta de código debido a cambiar la condición en sí).

 124
Author: caf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-21 03:16:33

De acuerdo con este manual:

El pthread_cond_broadcast() o pthread_cond_signal() funciones puede ser llamado por un hilo, ya sea que actualmente posea o no el mutex que threads calling pthread_cond_wait() o pthread_cond_timedwait() tienen asociado con la variable condición durante sus esperas; sin embargo, si comportamiento de programación predecible es requerido, entonces que mutex será bloqueado por el hilo que llama pthread_cond_broadcast() o pthread_cond_signal().

El significado del comportamiento de programación predecible la declaración fue explicada por Dave Butenhof (autor de Programación con hilos POSIX) en comp.programación.hilos y está disponible aquí.

 44
Author: icecrime,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-28 07:48:07

Caf, en su código de ejemplo, el Proceso B modifica condition sin bloquear primero el mutex. Si el Proceso B simplemente bloqueó el mutex durante esa modificación, y luego aún desbloqueó el mutex antes de llamar pthread_cond_signal, no habría ningún problema - - - ¿tengo razón sobre eso?

Creo intuitivamente que la posición de caf es correcta: llamar a pthread_cond_signal sin poseer el bloqueo mutex es una Mala Idea. Pero el ejemplo de caf no es realmente evidencia en apoyo de esta posición; es simplemente evidencia en apoyo de la posición mucho más débil (prácticamente evidente) de que es una Mala Idea modificar el estado compartido protegido por un mutex a menos que haya bloqueado ese mutex primero.

¿Puede alguien proporcionar algún código de ejemplo en el que llamar pthread_cond_signal seguido de pthread_mutex_unlock produce un comportamiento correcto, pero llamar pthread_mutex_unlock seguido de pthread_cond_signal produce un comportamiento incorrecto?

 4
Author: Quuxplusone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-07 23:13:43