Quali operazioni sono atomiche in C #?

Esiste un modo sistematico per sapere se un’operazione in C # sarà atomica o no? O ci sono delle linee guida generali o regole generali?

Per qualcosa di più completo / dettagliato:

Le letture e le scritture sui tipi di valore a 32 bit sono atomiche: include i seguenti tipi di valore intrinseco (struct): bool, char, byte, sbyte, short, ushort, int, uint, float . I seguenti tipi (tra gli altri) non sono garantiti per essere atomici: decimal, double, long, ulong .

per esempio

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

L’assegnazione di riferimento è anche un’operazione atomica:

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

Sì. Leggi le specifiche CLI: http://www.ecma-international.org/publications/standards/Ecma-335.htm . Per esempio:

I.12.6.6 Atomic legge e scrive

Una CLI conforms garantisce che l’accesso in lettura e scrittura a posizioni di memoria correttamente allineate non più grandi della dimensione nativa della parola (la dimensione del tipo nativo int) sia atomica (vedere §I.12.6.2) quando tutti gli accessi in scrittura a una posizione sono Le stesse dimensioni. Le scritture atomiche non alterano bit diversi da quelli scritti. A meno che non si utilizzi il controllo esplicito del layout (vedi Partizione II (Controlling Instance Layout)) per modificare il comportamento predefinito, gli elementi di dati non più grandi della dimensione naturale della parola (la dimensione di un nativo int) devono essere allineati correttamente. I riferimenti agli oggetti devono essere trattati come se fossero memorizzati nella dimensione della parola nativa.

[Nota: non vi è alcuna garanzia sull’aggiornamento atomico (lettura-modifica-scrittura) della memoria, eccetto per i metodi forniti a tale scopo come parte della libreria di classi (vedere Partizione IV). Una scrittura atomica di un “piccolo elemento di dati” (un elemento non più grande della dimensione nativa della parola) è necessaria per eseguire una lettura / modifica / scrittura atomica su hardware che non supporta la scrittura diretta su elementi di dati di piccole dimensioni. nota finale]

[Nota: non esiste un accesso atomico garantito ai dati a 8 byte quando la dimensione di un nativo int è di 32 bit, anche se alcune implementazioni potrebbero eseguire operazioni atomiche quando i dati sono allineati su un limite di 8 byte. nota finale]

Per quanto riguarda la domanda lunga 64 bit, Eric Lippert risponde qui: http://blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are-different-part- two.aspx

Le specifiche CLI effettivamente rafforzano le garanzie. La CLI garantisce che le letture e le scritture di variabili di tipi di valore che sono la dimensione (o inferiore) della dimensione naturale del puntatore del processore sono atomiche; se si sta eseguendo codice C # su un sistema operativo a 64 bit in una versione a 64 bit del CLR, allora anche le letture e le scritture di 64 bit e gli interi long vengono garantiti come atomici. Il linguaggio C # non lo garantisce, ma le specifiche runtime lo fanno. (Se si esegue codice C # in un ambiente che non è implementato da alcune implementazioni della CLI, ovviamente non si può fare affidamento su tale garanzia, contattare il fornitore che ha venduto il runtime se si desidera sapere quali garanzie forniscono).

Un altro punto sottile sull’accesso atomico è che il processore sottostante garantisce l’atomicità solo quando la variabile che viene letta o scritta è associata all’archiviazione allineata alla giusta posizione nella memoria. In definitiva la variabile sarà implementata come un puntatore alla memoria da qualche parte. Su un sistema operativo a 32 bit, quel puntatore deve essere equamente divisibile per 4 in modo che la lettura o la scrittura siano garantite come atomiche, e su un sistema operativo a 64 bit deve essere equamente divisibile per 8.

Dalle specifiche CLI puoi arrivare qui :

“Una CLI conforms garantisce che l’accesso in lettura e scrittura a posizioni di memoria correttamente allineate non più grandi della dimensione nativa della parola (la dimensione del tipo nativo int) è atomica …”

Sezione 12.5 dalla specifica C # qui :

“Le letture e le scritture dei seguenti tipi di dati devono essere atomiche: bool, char, byte, sbyte, short, ushort, uint, int, float e tipi di riferimento.” Inoltre: “… non vi è alcuna garanzia di modifica della lettura atomica- scrivere, come nel caso di incremento o decremento. ”

Rendi atomica l’operazione di incremento con questo .