2009-06-26 13 views
176

Ver varias preguntas relacionadas con el bloqueo y (casi) siempre encontrar el 'bucle debido a los despertadores espurios' Me pregunto si alguien ha experimentado tal tipo de activación (suponiendo un entorno de hardware/software decente, por ejemplo).¿Realmente ocurren los despertadores espurios?

Sé que el término "espúreo" no significa razón aparente, pero ¿cuáles pueden ser los motivos de tal tipo de evento?

(1 Nota: No estoy cuestionando la práctica de bucle.)

Editar: Una pregunta helper (para los que como ejemplos de código):

si tengo el siguiente programa y lo ejecuto:

public class Spurious { 
    public static void main(String[] args) { 
     Lock lock = new ReentrantLock(); 
     Condition cond = lock.newCondition(); 
     lock.lock(); 
     try { 
      try { 
       cond.await(); 
       System.out.println("Spurious wakeup!"); 
      } catch (InterruptedException ex) { 
       System.out.println("Just a regular interrupt."); 
      } 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

¿Qué puedo hacer para reactivar el await hasta falsamente sin esperar por siempre para un evento al azar?

Respuesta

175

La Wikipedia article on spurious wakeups tiene este dato:

La función pthread_cond_wait() en Linux se implementa utilizando la llamada futex sistema. Cada llamada al sistema de bloqueo en Linux vuelve abruptamente con EINTR cuando el proceso recibe una señal. ... pthread_cond_wait() no puede reiniciar la espera porque puede perder una activación real en el poco tiempo que estuvo fuera de la llamada al sistema futex. Esta condición de carrera solo se puede evitar si el que llama verifica un invariante. Una señal POSIX generará, por lo tanto, una activación espuria.

Resumen: Si un proceso Linux se señaliza sus hilos que esperan será cada disfrutar de una agradable, caliente de activación espuria.

Lo compro. Esa es una píldora más fácil de tragar que la razón por lo general vaga "por su rendimiento" que a menudo se da.

+11

Mejor explicación aquí: http://stackoverflow.com/questions/1461913/does-c-monitor-wait-suffer-from-spurious-wakeups/1461956#1461956 – Gili

+3

Este desbloqueo EINTR se aplica a todas las llamadas al sistema de bloqueo en Unix derivado sistemas. Esto simplificó los lotes del kernel, pero los programadores de aplicaciones compraron la carga. –

+1

Pensé que pthread_cond_wait() y amigos no podrían devolver EINTR, pero ¿devuelve cero si se despierta espurio? De: http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html "Estas funciones no devolverán un código de error de [EINTR]". – gubby

8

Cameron Purdy escribió un blog post hace un tiempo acerca de ser golpeado por el problema de activación espuria. Así que sí, sucede

Supongo que está en la especificación (como una posibilidad) debido a las limitaciones de algunas de las plataformas en las que se implementa Java. ¡aunque puedo estar equivocado!

+5

http://www.jroller.com/cpurdy/entry/java_supplies_apologies_to_weird – akarnokd

+0

Leí la publicación y me dio una idea acerca de tener pruebas unitarias para probar la conformidad de una aplicación con el paradigma de espera de bucle, activándolo al azar/determinísticamente . ¿O ya está disponible en algún lado? – akarnokd

+0

Es otra pregunta en SO: "¿Hay una * strict * VM que se pueda usar para probar?". Me encantaría ver uno con estricta memoria local de hilos. No creo que aún existan –

20

Tengo un sistema de producción que muestra este comportamiento. Un hilo espera una señal de que hay un mensaje en la cola. En períodos ocupados, hasta el 20% de los despertadores son espurios (es decir, cuando se despierta no hay nada en la cola). Este hilo es el único consumidor de los mensajes. Se ejecuta en una caja Linux SLES-10 de 8 procesadores y está construido con GCC 4.1.2. Los mensajes provienen de una fuente externa y se procesan de forma asíncrona porque existen problemas si mi sistema no los lee con la suficiente rapidez.

7

Solo para agregar esto. Sí, sucede y pasé tres días buscando la causa de un problema de subprocesos múltiples en una máquina de 24 núcleos (JDK 6). 4 de 10 ejecuciones experimentaron eso sin ningún patrón. Esto nunca sucedió en 2 núcleos u 8 núcleos.

Estudié un poco de material en línea y esto no es un problema de Java sino un comportamiento raro pero esperado.

+0

Hola ReneS, ¿estás desarrollando la aplicación que se está ejecutando allí? ¿Tiene (hizo) que el método wait() invoque el bucle while para verificar la condición externa tal como se sugiere en el doc de Java http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html# espera% 28% 29? – gumkins

+0

Escribí al respecto y sí, la solución es un ciclo while con una verificación de condición. Mi error fue el bucle perdido ... pero entonces aprendí sobre estos despertadores ... nunca en dos núcleos, a menudo en 24 códigos https://blog.xceptance.com/2011/05/06/spurious-wakeup-the-rare -evento/ – ReneS

11

Para responder la pregunta en el titile - ¡Sí! lo hace happen.Though la Wiki article menciones bastante sobre activaciones falsas una buena explicación de la misma que me encontré es el siguiente -

Sólo pensar en ello ... como cualquier código, programador de subprocesos puede experimentar Apagón temporal debido a que algo anormal sucede en el hardware/software subyacente. Por supuesto, se debe tener cuidado de que esto ocurra lo más raro posible, pero como no existe un software 100% robusto, es razonable suponer que esto puede suceder y tener cuidado con la elegante recuperación en caso de que el planificador detecte esto (p. Ej. observando latidos cardíacos faltantes).

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

Esto hace necesario establecer un "contrato" que el hilo de espera puede ser notificado sin una razón. Para ser precisos, habría una razón, el apagón del programador, pero dado que el hilo está diseñado (por una buena razón) para no tener en cuenta los detalles de la implementación interna del programador, es probable que esta razón se presente como "espuria".

Estaba leyendo esta respuesta desde Source y considero que es lo suficientemente razonable. Lea también

Spurious wakeups in Java and how to avoid them.

Cuestiones relacionadas