C# 中哪些操作是原子的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11745440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What operations are atomic in C#?
提问by Eric
Is there a systematic way to know whether an operation in C# will be atomic or not? Or are there any general guidelines or rules of thumb?
有没有系统的方法来知道 C# 中的操作是否是原子的?或者是否有任何一般准则或经验法则?
采纳答案by Peter Ritchie
For something more complete/detailed:
对于更完整/详细的内容:
Reads and writes to 32-bit value types are atomic: This includes the following intrinsic value (struct) types: bool, char, byte, sbyte, short, ushort, int, uint, float. The following types (amongst others) are not guaranteed to be atomic: decimal, double, long, ulong.
对 32 位值类型的读取和写入是原子的:这包括以下内在值 (struct) 类型:bool, char, byte, sbyte, short, ushort, int, uint, float. 以下类型(除其他外)不能保证是原子的:decimal, double, long, ulong.
e.g.
例如
int x;
x = 10; // atomic
decimal d;
d = 10m; // not atomic
Reference assignment is also an atomic operation:
引用赋值也是一个原子操作:
private String _text;
public void Method(String text)
{
_text = text; // atomic
}
回答by Chris Shain
Yes. Read the CLI specification: http://www.ecma-international.org/publications/standards/Ecma-335.htm. For instance:
是的。阅读 CLI 规范:http: //www.ecma-international.org/publications/standards/Ecma-335.htm。例如:
I.12.6.6 Atomic reads and writes
I.12.6.6 原子读写
A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic (see §I.12.6.2) when all the write accesses to a location are the same size. Atomic writes shall alter no bits other than those written. Unless explicit layout control (see Partition II (Controlling Instance Layout)) is used to alter the default behavior, data elements no larger than the natural word size (the size of a native int) shall be properly aligned. Object references shall be treated as though they are stored in the native word size.
[Note: There is no guarantee about atomic update (read-modify-write) of memory, except for methods provided for that purpose as part of the class library (see Partition IV). An atomic write of a “small data item” (an item no larger than the native word size) is required to do an atomic read/modify/write on hardware that does not support direct writes to small data items. end note]
[Note: There is no guaranteed atomic access to 8-byte data when the size of a native int is 32 bits even though some implementations might perform atomic operations when the data is aligned on an 8-byte boundary. end note]
一个符合标准的 CLI 应保证对不大于本地字大小(本地 int 类型的大小)的正确对齐的内存位置的读写访问是原子的(参见 §I.12.6.2),当对一个位置的所有写访问都是相同的大小。原子写操作不得更改除写入的位以外的任何位。除非使用显式布局控制(参见第 II 部分(控制实例布局))来改变默认行为,否则不大于自然字大小(本机 int 的大小)的数据元素应正确对齐。对象引用应被视为以本地字大小存储。
[注意:除了作为类库的一部分为此目的提供的方法外,不能保证内存的原子更新(读取-修改-写入)(参见第 IV 部分)。需要对“小数据项”(不大于本机字大小的项)进行原子写入,才能在不支持直接写入小数据项的硬件上进行原子读取/修改/写入。尾注]
[注意:当本机 int 的大小为 32 位时,无法保证对 8 字节数据的原子访问,即使当数据在 8 字节边界上对齐时某些实现可能会执行原子操作。尾注]
Regarding the 64-bit long question, Eric Lippert answers it here: http://blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are-different-part-two.aspx
关于 64 位长问题,Eric Lippert 在这里回答:http: //blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are-different-part-二.aspx
The CLI specification actually makes stronger guarantees. The CLI guarantees that reads and writes of variables of value types that are the size (or smaller) of the processor's natural pointer size are atomic; if you are running C# code on a 64 bit operating system in a 64 bit version of the CLR then reads and writes of 64 bit doubles and long integers are also guaranteed to be atomic. The C# language does not guarantee that, but the runtime spec does. (If you are running C# code in some environment that is not implemented by some implementation of the CLI then of course you cannot rely upon that guarantee; contact the vendor who sold you the runtime if you want to know what guarantees they provide.)
Another subtle point about atomic access is that the underlying processor only guarantees atomicity when the variable being read or written is associated with storage that is aligned to the right location in memory. Ultimately the variable will be implemented as a pointer to memory somewhere. On a 32 bit operating system, that pointer has to be evenly divisible by 4 in order for the read or write to be guaranteed to be atomic, and on a 64 bit operating system it has to be evenly divisible by 8.
CLI 规范实际上提供了更强的保证。CLI 保证读取和写入处理器自然指针大小(或更小)的值类型变量是原子的;如果您在 64 位版本的 CLR 中的 64 位操作系统上运行 C# 代码,那么读取和写入 64 位双精度和长整数也保证是原子的。C# 语言不能保证这一点,但运行时规范可以。(如果您在某些 CLI 实现未实现的环境中运行 C# 代码,那么您当然不能依赖该保证;如果您想知道他们提供什么保证,请联系向您出售运行时的供应商。)
关于原子访问的另一个微妙之处是,底层处理器仅在读取或写入的变量与对齐到内存中正确位置的存储相关联时才保证原子性。最终,该变量将被实现为指向某处内存的指针。在 32 位操作系统上,该指针必须被 4 整除才能保证读取或写入是原子的,而在 64 位操作系统上,它必须被 8 整除。
回答by Secko
From the CLI specifications you can get here:
从 CLI 规范你可以得到这里:
"A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic…”
“符合标准的 CLI 应保证对不大于本机字大小(本机 int 类型的大小)的正确对齐的内存位置的读写访问是原子的……”
Section 12.5 from the C# specification here:
此处C# 规范的第 12.5 节:
“Reads and writes of the following data types shall be atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types.” Also: “…there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement.”
“以下数据类型的读写应该是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。” 另外:“……无法保证原子读-修改-写,例如在递增或递减的情况下。”
Make the increment operation atomic with this.
使用this使增量操作原子化。

