tag near kichink descripcion agency c multithreading pthreads

near - Condiciones de rosca y espera.



tag agency near me (2)

La verdadera razón por la que debe poner pthread_cond_wait en un bucle while no es debido a una activación falsa. Incluso si su variable de condición no tuviera una activación falsa, aún necesitaría el bucle para detectar un tipo de error común. ¿Por qué? Considere lo que puede suceder si varios subprocesos esperan en la misma condición:

Thread 1 Thread 2 Thread 3 check condition (fails) (in cond_wait) unlock mutex (in cond_wait) wait lock mutex set condition signal condvar unlock mutex lock mutex check condition (succeeds) do stuff unset condition unlock mutex (in cond_wait) wake up (in cond_wait) lock mutex <thread is awake, but condition is unset>

El problema aquí es que el subproceso debe liberar el mutex antes de esperar, lo que potencialmente permite que otro subproceso "robe" lo que el subproceso estaba esperando. A menos que se garantice que solo un hilo puede esperar en esa condición, es incorrecto suponer que la condición es válida cuando un hilo se despierta.

Estoy aprendiendo pthread y esperar condiciones. Por lo que puedo decir, un hilo de espera típico es así:

pthread_mutex_lock(&m); while(!condition) pthread_cond_wait(&cond, &m); // Thread stuff here pthread_mutex_unlock(&m);

Lo que no entiendo es por qué la línea while(!condition) es necesaria incluso si uso pthread_cond_signal() para activar el hilo.

Puedo entender que si uso pthread_cond_broadcast() necesito probar la condición, porque reactivo todos los hilos en espera y uno de ellos puede hacer que la condición vuelva a ser falsa antes de desbloquear la exclusión (y así transferir la ejecución a otro hilo que no debería ejecutar en ese punto). Pero si uso pthread_cond_signal() me despierto solo un hilo por lo que la condición debe ser verdadera. Entonces el código podría verse así:

pthread_mutex_lock(&m); pthread_cond_wait(&cond, &m); // Thread stuff here pthread_mutex_unlock(&m);

Leí algo sobre señales espurias que pueden suceder. ¿Es esta (y solo esta) la razón? ¿Por qué debería tener singulares espurias? ¿O hay algo más que no entiendo?

Asumo que el código de señal es así:

pthread_mutex_lock(&m); condition = true; pthread_cond_signal(&cond); // Should wake up *one* thread pthread_mutex_unlock(&m);


Supongamos que no se comprueba la condición. Entonces, por lo general, no puede evitar que ocurra lo siguiente (al menos, no puede evitarlo en una línea de código):

Sender Receiver locks mutex sets condition signals condvar, but nothing is waiting so has no effect releases mutex locks mutex waits. Forever.

Por supuesto, su segundo ejemplo de código podría evitar esto haciendo:

pthread_mutex_lock(&m); if (!condition) pthread_cond_wait(&cond, &m); // Thread stuff here pthread_mutex_unlock(&m);

Entonces, ciertamente sería el caso de que si solo hubiera un solo receptor, y si cond_signal fuera lo único que pudiera despertarlo, solo se cond_signal cuando se estableciera la condición y, por lo tanto, no necesitaría un bucle. . nos cubre por qué el segundo "si" no es cierto.