comprensión de pthread_cond_wait () y pthread_cond_signal ()

En general, pthread_cond_wait() y pthread_cond_signal() se llaman de la siguiente manera:

 //thread 1: pthread_mutex_lock(&mutex); pthread_cond_wait(&cond, &mutex); do_something() pthread_mutex_unlock(&mutex); //thread 2: pthread_mutex_lock(&mutex); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); 

Los pasos son

  1. pthread_cond_wait(&cond, &mutex); se llama, desbloquea el mutex

  2. El hilo 2 bloquea el mutex y llama a pthread_cond_signal() , que desbloquea el mutex

  3. En el hilo 1, pthread_cond_wait() se llama y bloquea el mutex de nuevo

Ahora en el hilo 2, después de llamar a pthread_cond_signal() , pthread_mutex_unlock(&mutex) va a ejecutarse, me parece que quiere desbloquear el mutex que ahora está bloqueado por el hilo 1. ¿Hay algo de malo en mi comprensión?

Además, también me parece que pthread_cond_wait() se puede llamar con 1 hilo para el mismo par cond-mutex. Pero hay un refrán que dice: “La función pthread_cond_signal () desbloqueará al menos uno de los hilos que están bloqueados en la cond de variable de condición especificada (si alguno de los hilos está bloqueado en cond)”. Entonces, ¿significa que pthread_cond_wait() puede ser invocado por muchos hilos para el mismo par cond-mutex?

pthread_cond_signal no desbloquea el mutex (no puede porque no tiene referencia al mutex, entonces, ¿cómo podría saber qué desbloquear?) De hecho, la señal no necesita tener ninguna conexión con el mutex; el hilo de señalización no necesita mantener el mutex, aunque para la mayoría de los algoritmos basados ​​en variables de condición lo hará.

pthread_cond_wait desbloquea el mutex justo antes de que duerma (como se observa), pero luego se requiere el mutex (que puede requerir esperar) cuando se señaliza, antes de que se active. Entonces, si el hilo de señalización contiene el mutex (el caso habitual), el hilo de espera no continuará hasta que el hilo de señalización también desbloquee el mutex.

El uso común de condicion vars es algo así como:

 thread 1: pthread_mutex_lock(&mutex); while (!condition) pthread_cond_wait(&cond, &mutex); /* do something that requires holding the mutex and condition is true */ pthread_mutex_unlock(&mutex); thread2: pthread_mutex_lock(&mutex); /* do something that might make condition true */ pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); 

Los dos hilos tienen una estructura de datos compartida a la que el mutex protege el acceso. El primer subproceso quiere esperar hasta que alguna condición sea verdadera e inmediatamente realizar alguna operación (sin condición de condición de carrera para que otro subproceso entre la comprobación de condición y la acción y haga que la condición sea falsa). El segundo subproceso está haciendo algo que podría hacer que la condición sea verdadera, por lo que debe despertar a cualquier persona que pueda estar esperándolo.

Aquí hay un ejemplo típico: el hilo 1 está esperando una condición, que puede ser cumplida por el hilo 2 .

Usamos un mutex y una condición.

 pthread_mutex_t mutex; pthread_cond_t condition; 

hilo 1:

 pthread_mutex_lock(&mutex); //mutex lock while(!condition){ pthread_cond_wait(&condition, &mutex); //wait for the condition } /* do what you want */ pthread_mutex_unlock(&mutex); 

hilo 2:

 pthread_mutex_lock(&mutex); /* do something that may fulfill the condition */ pthread_mutex_unlock(&mutex); pthread_cond_signal(&condition); //wake up thread 1 

Editar

Como puede ver en el manual pthread_cond_wait :

Atómica libera mutex y hace que el hilo de llamada bloquee en la condición condición cond; Atómicamente aquí significa “atómicamente con respecto al acceso de otro hilo al mutex y luego a la variable de condición”.