¿Qué operaciones son atómicas en C #?

¿Hay una manera sistemática de saber si una operación en C # será atómica o no? ¿O hay alguna guía general o reglas generales?

Para algo más completo / detallado:

Lee y escribe en los tipos de valores de 32 bits son atómicos: Esto incluye los siguientes tipos de valores intrínsecos (struct): bool, char, byte, sbyte, short, ushort, int, uint, float . No se garantiza que los siguientes tipos (entre otros) sean atómicos: decimal, double, long, ulong .

p.ej

 int x; x = 10; // atomic decimal d; d = 10m; // not atomic 

La asignación de referencia también es una operación atómica:

 private String _text; public void Method(String text) { _text = text; // atomic } 

Sí. Lea la especificación CLI: http://www.ecma-international.org/publications/standards/Ecma-335.htm . Por ejemplo:

I.12.6.6 Lecturas y escrituras atómicas

Una CLI conforme debe garantizar que el acceso de lectura y escritura a ubicaciones de memoria alineadas correctamente no mayores que el tamaño de la palabra nativa (el tamaño del tipo native int) es atómico (ver §I.12.6.2) cuando todos los accesos de escritura a una ubicación son el mismo tamaño. Las escrituras atómicas no alterarán ningún otro que los escritos. A menos que se utilice un control de disposición explícito (vea Partición II (Controlar el diseño de instancia)) para alterar el comportamiento predeterminado, los elementos de datos no mayores que el tamaño de palabra natural (el tamaño de un int nativo) se alinearán correctamente. Las referencias a objetos se tratarán como si estuvieran almacenadas en el tamaño de la palabra nativa.

[Nota: no hay garantía acerca de la actualización atómica (lectura-modificación-escritura) de la memoria, a excepción de los métodos proporcionados para tal fin como parte de la biblioteca de clases (ver Partición IV). Se requiere una escritura atómica de un “elemento de datos pequeños” (un elemento no más grande que el tamaño de la palabra nativa) para hacer una lectura atómica / modificar / escribir en el hardware que no admite escrituras directas para elementos de datos pequeños. nota final]

[Nota: no se garantiza el acceso atómico a datos de 8 bytes cuando el tamaño de un int nativo es de 32 bits, aunque algunas implementaciones pueden realizar operaciones atómicas cuando los datos están alineados en un límite de 8 bytes. nota final]

Con respecto a la pregunta larga de 64 bits, Eric Lippert la responde aquí: http://blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are-different-part- two.aspx

La especificación CLI realmente hace garantías más fuertes. La CLI garantiza que las lecturas y escrituras de variables de tipos de valores que son del tamaño (o menor) del tamaño del puntero natural del procesador son atómicas; si está ejecutando el código C # en un sistema operativo de 64 bits en una versión de 64 bits del CLR, entonces las lecturas y escrituras de dobles de 64 bits y enteros largos también se garantiza que serán atómicas. El lenguaje C # no garantiza eso, pero sí lo hace la especificación de tiempo de ejecución. (Si está ejecutando código C # en algún entorno que no está implementado por alguna implementación de la CLI, por supuesto no puede confiar en esa garantía, póngase en contacto con el proveedor que le vendió el tiempo de ejecución si desea saber qué garantías ofrecen).

Otro punto sutil acerca del acceso atómico es que el procesador subyacente solo garantiza la atomicidad cuando la variable que se lee o escribe está asociada con el almacenamiento que está alineado con la ubicación correcta en la memoria. En última instancia, la variable se implementará como un puntero a la memoria en alguna parte. En un sistema operativo de 32 bits, ese puntero tiene que ser divisible por 4 para que la lectura o escritura se garantice que es atómica, y en un sistema operativo de 64 bits debe ser divisible por 8.

A partir de las especificaciones CLI, puede obtenerlas aquí :

“Una CLI conforme debe garantizar que el acceso de lectura y escritura a ubicaciones de memoria alineadas correctamente no mayores que el tamaño de la palabra nativa (el tamaño del tipo native int) es atómico …”

La sección 12.5 de la especificación C # aquí :

“Las lecturas y escrituras de los siguientes tipos de datos serán atómicas: bool, char, byte, sbyte, corto, ushort, uint, int, float y tipos de referencia.” Además: “… no hay garantía de lectura atómica-modificación- escribir, como en el caso de incremento o disminución “.

Haga la operación de incremento atómica con esto .