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.