2011-04-28 21 views
14

he encontrado varias preguntas sobre este mismo tema, pero en relación con las variables generales (tipos de valor y de referencia) La respuesta aceptada de this question dice:¿La asignación de referencia y la lectura de operaciones atómicas?

partición I, sección 12.6.6 de los estados de especificaciones de la CLI: "Un conforme CLI garantizará que el acceso de lectura y escritura a ubicaciones de memoria alineadas correctamente no mayores que el tamaño de la palabra nativa es atómico cuando todos los accesos de escritura a una ubicación son del mismo tamaño ".

Las variables de referencia (es decir, las clases) son punteros, igual al tamaño de la palabra nativa, pero tengo un par de dudas:

aparecen referencias garantiza que sea localizaciones de memoria correctamente alineados?

No entiendo la última parte. ¿Qué significa esto? "... cuando todos los accesos de escritura a una ubicación son del mismo tamaño".

En resumen, ¿se garantiza que obj2 sea válido en cada iteración del ciclo en el siguiente código?

class MyClass 
{ 
    private OtherClass m_Object; 

    void Thread1() 
    { 
     while(true) 
     { 
      OtherClass obj1 = new OtherClass(); 
      m_Object = obj1; 
     } 
    } 

    void Thread2() 
    { 
     while (true) 
     { 
      OtherClass obj2 = m_Object; 
      // Is obj2 guaranteed to be valid? 
      obj2.Check(); 
     } 
    } 
} 

Respuesta

10

Sí, todo lo que se garantiza que sea alineado correctamente a menos que vaya deliberadamente fuera de su camino a desalinear las cosas, lo que significa que la asignación de referencia/lectura se garantiza que sea atómica.

Sección 12.6.6 de la especificación CLI va a decir esto:

A menos que el control de la disposición explícita (ver partición II (Control de Instancia Layout)) se utiliza para modificar el comportamiento predeterminado , los datos los elementos no mayores que el tamaño de palabra natural (el tamaño de native int) debe estar correctamente alineado con . Las referencias a objetos serán tratados como si se almacenan en el tamaño nativo palabra.

También hay más detalles sobre la alineación, etc. en la sección 12.6.2 de la especificación.

Tenga en cuenta que en el código de ejemplo, la lectura de rosca 2 se garantiza que sea atómica, pero es no garantizado para ver realmente los cambios realizados por el hilo 1: sin imponer barreras de memoria o la volatilidad de cada hilo puede utilizar su propio "vista" del campo m_Object sin ver los cambios realizados por otros subprocesos.

Así, por ejemplo, el subproceso 1 podría estar haciendo grabaciones (atómicas) en su propia vista de m_Object, pero los datos solo se guardan realmente en un registro o caché de CPU y nunca se guardan en la memoria principal. De forma similar, el subproceso 2 también podría estar haciendo lecturas (atómicas) de m_Object, pero en realidad leyendo desde un registro o caché de CPU en lugar de desde la memoria principal.

+0

eso es bastante interesante, gracias. ¿Qué sucede si dentro de los bucles, en lugar de la lectura/asignación directa de la variable m_Object, hay llamadas a métodos que realmente hicieron la lectura/asignación? ¿El problema de volatilidad todavía existiría? – raven

+0

@Jaime: Sí, a menos que haya algún tipo de sincronización forzada - campo volátil, barrera de memoria, bloqueo, etc llamar 'Interlocked' - entonces aún puede ocurrir. (En mi experiencia, este tipo de cosas no muerde muy a menudo, pero * sí * ocasionalmente, así que es mejor evitarlo por completo). – LukeH

Cuestiones relacionadas