Si no bloquea el mutex en la ruta de código que cambia la condición y las señales, puede perder las activaciones. 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);
Luego considere este posible entrelazado 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
es ahora TRUE
, pero el proceso A está atascado esperando en la variable de condición: perdió la señal de activación. Si modificamos el 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 en realidad puede mover el pthread_cond_signal()
mismo después de pthread_mutex_unlock()
, pero esto puede resultar en una programación de subprocesos menos óptima, y necesariamente ha bloqueado el mutex ya en esta ruta de código debido al cambio de la condición en sí).
pthread_signal_cond()
se puede mover después del desbloqueo de mutex, aunque probablemente sea mejor no hacerlo. Quizás sea más correcto decir que en el punto donde está llamandopthread_signal_cond()
, ya habrá necesitado haber bloqueado el mutex para modificar la condición en sí.