2011-08-30 7 views
5

En este libro en línea enhebrar: http://www.albahari.com/threading/part4.aspxentendimiento sincronización de hilos de bloqueo y no Thread.MemoryBarrier

theres un ejemplo de Thread.MemoryBarrier()

class Foo 
{ 
    int _answer; 
    bool _complete; 

    void A() 
    { 
    _answer = 123; 
    Thread.MemoryBarrier(); // Barrier 1 
    _complete = true; 
    Thread.MemoryBarrier(); // Barrier 2 
    } 

    void B() 
    { 
    Thread.MemoryBarrier(); // Barrier 3 
    if (_complete) 
    { 
     Thread.MemoryBarrier();  // Barrier 4 
     Console.WriteLine (_answer); 
    } 
    } 
} 

Tenemos una discusión si existe algún bloqueo hilo pasando o no?

Im pensar que hay algunos, sobre todo teniendo en cuenta que

Una valla completa dura alrededor de diez nanosegundos en un escritorio 2010 de la era.

Por otra parte, cerca completo solamente se supone que disable instructions reodering and caching que por su sonido no califica como bloqueo de rosca, (a diferencia lock donde es claro que para otro hilo espera para liberar el bloqueo antes de que continúe, y se bloquea durante ese tiempo)

Acerca de ese hilo 'estado de bloque'. Estoy hablando no en términos de si el hilo se pone en estado bloqueado o no, pero si hay alguna sincronización de hilo que ocurre, lo que significa que un hilo no se puede ejecutar mientras que otro no lo permite, por medio de MemoryBarrier en este caso.

También me gustaría obtener una idea clara de lo que logra cada barrera. Por ejemplo, Barrier 2: ¿cómo proporciona exactamente la garantía de frescura y cómo está conectada a la barrera 3? Si alguien explicara en detalle cuál es el propósito de cada barrera aquí (lo que posiblemente podría salir mal si 1 o 2 o 3 o 4 no estuvieran allí) creo que puedo mejorar mi comprensión de esto en gran medida.

EDITAR: es bastante claro ahora lo que 1, 2 y 3 hacen. Sin embargo, lo que 4 no hace 3 no está claro.

Respuesta

5

El hecho de que las instrucciones tarden en ejecutarse hace no implica que un hilo está bloqueado. Un hilo está bloqueado cuando se pone específicamente en un estado bloqueado, lo que MemoryBarrier() no hace.

Las instrucciones del procesador que realmente impiden el reordenamiento de la instrucción y la limpieza del caché toman tiempo, porque deben esperar a que las cachés vuelvan a ser coherentes. Durante ese tiempo, el hilo todavía se considera en ejecución.

Actualización: Echemos un vistazo a lo que está sucediendo realmente en el ejemplo y lo que hace cada barrera de memoria.

Como dice el enlace, 1 y 4 aseguran que se producen las respuestas correctas. Esto se debe a que 1 asegura que las respuestas se descarguen en la memoria y 4 garantiza que las memorias caché de lectura se vacíen antes de recuperar las variables.

2 y 3 aseguran que si A se ejecuta primero, entonces Bsiempre imprime las respuestas. La barrera 2 asegura que la escritura de true se vacía en la memoria, y la barrera 3 asegura que las cavidades de lectura se limpien antes de probar el valor de _complete.

La limpieza de la memoria caché y de la memoria debe ser lo suficientemente clara, así que echemos un vistazo al reordenamiento de las instrucciones.La forma en que el compilador, el CLR y la CPU saben que pueden reordenar las instrucciones es analizando un conjunto de instrucciones en secuencia. Cuando ven la instrucción de barrera en el medio de una secuencia, saben que las instrucciones no pueden moverse a través de ese límite. Eso asegura que, además de la frescura del caché, las instrucciones se producen en el orden correcto.

+0

seguro que no implica que directamente, solo pensé que podría considerarse como una evidencia, es lógico que el comando tome tiempo para ejecutarse. –

+0

@Valentin Se podría considerar evidencia, pero simplemente no es el caso aquí :) – dlev

+0

bien, vea mi edición al final de la pregunta, y mientras estamos en esto, ¿la declaración de bloqueo pone un hilo en estado bloqueado (solo para aclarar ese hilo bloqueó la definición de estado)? –

Cuestiones relacionadas