La explicación espuria de los despertares suena como un error que no vale la pena solucionar, ¿verdad?

30

Según el artículo de Wikipedia sobre Spurious Wakeups

"un hilo puede despertarse de su estado de espera aunque ningún hilo indique la variable de condición".

Si bien conozco esta 'característica', nunca supe qué la causó hasta que, en el mismo artículo

"El despertar espurio puede sonar extraño, pero en algunos sistemas multiprocesador, hacer que el despertar de la condición sea completamente predecible podría ralentizar sustancialmente todas las operaciones variables de la condición".

Suena como un error que no vale la pena solucionar, ¿verdad?

James
fuente
1
relacionado: "¿Por qué pthread_cond_wait tiene despertadores espurios?", stackoverflow.com/questions/8594591/…
Florian Castellane

Respuestas:

39

TL; DR Asunción ("contrato") de reactivaciones espurias es una decisión arquitectónica sensata tomada para permitir implementaciones realistas y robustas del programador de hilos.

Las "consideraciones de rendimiento" son irrelevantes aquí, estos son solo malentendidos que se generalizaron por haber declarado en una referencia autorizada publicada. (las referencias autorizadas pueden tener errores, ya sabes, solo pregúntale a Galileo Galilei ) El artículo de Wikipedia mantiene la referencia a la nota que citaste solo porque coincide perfectamente con sus pautas formales de citar la referencia publicada.

En esta respuesta en SO se proporciona una razón mucho más convincente para introducir el concepto de despertadores espurios, que se basa en detalles adicionales proporcionados en una (versión anterior) de ese mismo artículo:

El artículo de Wikipedia sobre despertares espurios tiene este :

La pthread_cond_wait()función en Linux se implementa mediante la futexllamada al sistema. Cada llamada al sistema de bloqueo en Linux regresa abruptamente EINTRcuando el proceso recibe una señal. ... pthread_cond_wait()no puede reiniciar la espera porque puede perder una verdadera activación en el poco tiempo que estuvo fuera de la futexllamada del sistema ...

Solo piense en ello ... como cualquier código, el programador de subprocesos puede experimentar un apagón temporal debido a algo anormal que ocurre en el hardware / software subyacente. Por supuesto, se debe tener cuidado para que esto suceda lo más raro posible, pero dado que no existe un software 100% robusto, es razonable suponer que esto puede suceder y tener cuidado con la recuperación elegante en caso de que el programador detecte esto (p. Ej. observando los latidos perdidos ).

Ahora, ¿cómo podría recuperarse el planificador, teniendo en cuenta que durante el apagón podría perder algunas señales destinadas a notificar subprocesos en espera? Si el planificador no hace nada, los hilos "desafortunados" mencionados simplemente se colgarán, esperando por siempre; para evitar esto, el planificador simplemente enviará una señal a todos los hilos en espera.

Esto hace que sea necesario establecer un "contrato" para que el hilo de espera pueda ser notificado sin motivo. Para ser precisos, habría una razón, el apagón del planificador, pero dado que el subproceso está diseñado (por una buena razón) para ser ajeno a los detalles de implementación interna del planificador, es probable que esta razón sea mejor presentarla como "espuria".


Desde la perspectiva del hilo, esto se parece un poco a la ley de Postel (también conocido como principio de robustez ),

sé conservador en lo que haces, sé liberal en lo que aceptas de los demás

La suposición de reactivaciones espurias obliga al hilo a ser conservador en lo que hace : establezca la condición al notificar a otros hilos y liberal en lo que acepta : verifique la condición al regresar de la espera y repita la espera si aún no está allí.

mosquito
fuente
10
Ugh ... la ley de Postel ... la razón por la cual HTML y todo tipo de tecnologías web tienen tanta basura (por ejemplo, la aceptación de HTML de la anidación de etiquetas incorrectas). Aparte de eso, buena respuesta.
Thomas Eding
3
La ley de Postel es la razón por la cual muchos errores no se detectan durante años porque bueno, incluso si su función devuelve el resultado incorrecto, ¡la aplicación parece funcionar! El mejor invento de todos.
Pacerier
2
@Pacerier: la función que devuelve una salida incorrecta no sigue la ley de Postel (parte conservadora).
YvesgereY
@Pacerier: OTOH, exigir que otros componentes sean estrictos para que los errores puedan detectarse antes es una posición interesante, errando del lado del principio 'Fail Fast' y el diseño 'Contract Based'.
YvesgereY
1

No vale la pena arreglarlo, ya que el código de la persona que llama debe usar el mismo tratamiento (verificar la condición) de todos modos, para lidiar con la condición de la carrera.

Un tratamiento para dos problemas, que resumen a continuación:

Despertar espurio: el subproceso de espera se programa antes de que se establezca la condición.
Sueño forzado: el subproceso en espera se programa después de que la condición se haya falsificado nuevamente.

Dado que lo posterior podría suceder, algunos llegaron al punto de introducir un espurio despertar en el contrato:

  • para imponer buenas prácticas al requerir bucles de predicados.
  • dar cierta libertad para la implementación del planificador (incluida una opción de recuperación de emergencia, como lo señala @gnat).

Referencia SO

YvesgereY
fuente
Me gustaría hacer +1 en esto, pero por la idea de que alguien introdujo intencionalmente despertadores espurios para que las personas que llaman agreguen bucles de predicados para abordar los sobresaltos forzados. Me parece inconcebible.
ruakh
"La intención era forzar el código correcto / robusto al requerir bucles de predicados". Ver el enlace provisto.
YvesgereY