Di que tienes este código
pthread_mutex_lock(&cam->video_lock);
while(cam->status == WAIT_DISPLAY) // <-- Why is this a 'while' and not an 'if'?
pthread_cond_wait(&cam->video_cond, &cam->video_lock);
pthread_mutex_unlock(&cam->video_lock);
Mi pregunta es, ¿por qué necesita un ciclo while aquí? no lo haría pthread_cond_wait solo espera hasta que el hilo de señalización señale cam_video_cond? Bien, sé que podrías tener un caso en el que cámara->estado no es igual a ESPERA_DISPAY Cuándo pthread_cond_wait se llama, pero en ese caso podría comprobarlo a través de un si condición en lugar de usar tiempo.
¿Me estoy perdiendo de algo? mi comprensión de pthread_cond_wait es que solo espera infinito si cam_video_cond no está señalizado. Además, desbloquea el cam_video_lock mutex cuando se llama, pero cuando se señala la condición, antes de regresar, se vuelve a bloquear cam_video_lock. ¿Tengo razón?
Se recomienda que todos los subprocesos verifiquen la condición después de regresar de pthread_cond_wait porque hay varias razones por las que la condición podría no ser cierta. Una de estas razones es una activación espuria; es decir, un subproceso podría despertarse aunque ningún subproceso haya señalado la condición.
Fuente : despertar espurio
Las activaciones espurias son una razón, pero las activaciones legítimas pero extrañas son otra.
Considerar:
-
Pones un trabajo en una cola.
-
Señala la variable de condición, activando el subproceso A.
-
Pones un trabajo en una cola.
-
Señala la variable de condición, activando el subproceso B.
-
El subproceso A se programa, hace el primer trabajo.
-
El subproceso A encuentra que la cola no está vacía y realiza el segundo trabajo.
-
El subproceso B se programa después de haber sido activado, pero encuentra que la cola aún está vacía.
Por motivos de rendimiento, la API de POSIX permite que el sistema operativo active su subproceso incluso si la condición no se ha cumplido (eso se denomina despertar espurio).
La razón de la necesidad de usar mientras bucle es que sólo hay dos funciones en el std::condition_variable
para despertar hilos de espera:
notify_one()
que despierta uno de los subprocesos que actualmente esperan esta condición sin posibilidad de señalar cuál despertar exactamente.
notify_all()
que despierta todos los subprocesos que actualmente esperan esta condición.
Y porque std::condition_variable tiene solo dos funciones para despertar hilos en espera despertarás un hilo aleatorio usando notify_one()
o despierta todos los subprocesos en espera usando notify_all()
.
Obviamente eso no es satisfactorio. y necesitamos de alguna manera señalar cuál hilo debe despertar. Y en esa situación esta semántica puede ayudar:
while (!ready) cv.wait(lck);
resto parte del código
aquí, ready
– el resultado del predicado que devolverá verdadero solo cuando tenga lugar la condición particular que necesita.
Cotización:
Las variables de condición se utilizan para esperar hasta que un predicado de condición en particular se vuelva verdadero. Este predicado de condición lo establece otro subproceso, generalmente el que señala la condición.
Semántica de espera de condición
Un predicado de condición debe estar protegido por un mutex. Cuando se espera una condición, la subrutina de espera (ya sea la subrutina pthread_cond_wait o pthread_cond_timedwait) desbloquea atómicamente el mutex y bloquea el subproceso. Cuando se señala la condición, el mutex se vuelve a bloquear y vuelve la subrutina de espera. Es importante tener en cuenta que cuando la subrutina regresa sin error, el predicado aún puede ser falso.
La razón es que se puede despertar más de un subproceso: ya sea un subproceso llamado subrutina pthread_cond_broadcast, o una carrera inevitable entre dos procesadores simultáneamente despertó dos subprocesos. El primer subproceso que bloquea el mutex bloqueará todos los demás subprocesos activados en la subrutina de espera hasta que el programa desbloquee el mutex. Por lo tanto, el predicado puede haber cambiado cuando el segundo subproceso obtiene la exclusión mutua y regresa de la subrutina de espera.
En general, cada vez que se devuelve una espera de condición, el subproceso debe volver a evaluar el predicado para determinar si puede continuar con seguridad, si debe esperar de nuevo o si debe declarar un tiempo de espera. Un retorno de la subrutina de espera no implica que el predicado sea verdadero o falso. Se recomienda que una condición de espera se incluya en un “bucle while” que verifique el predicado.
Además: según la dificultad para crear condiciones de activación, que pueden ser impredecibles en sistemas multiproceso, los subprocesos pueden despertarse en cualquier momento por cualquier motivo. Eso se llama despertar espurio. Solución: use bucle para verificar siempre una variable de condición.
La misma pregunta aquí, unix.com/programming/149791-condiciones-variables.html
– Sacerdote Metálico
14 de octubre de 2011 a las 10:16
despertar espurio
– Príncipe Juan Wesley
14/10/2011 a las 10:21