是否有系统的方法来了解C#中的操作是否是原子操作?或者是否有任何一般指导方针或经验法则?
答案 0 :(得分:30)
更完整/更详细的内容:
对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
引用赋值也是一个原子操作:
private String _text;
public void Method(String text)
{
_text = text; // atomic
}
答案 1 :(得分:28)
是。阅读CLI规范:http://www.ecma-international.org/publications/standards/Ecma-335.htm。例如:
I.12.6.6原子读写
符合标准的CLI应保证对其的读写访问权限 正确对齐的内存位置不大于本机字大小 (native int类型的大小)是原子的(参见§I.12.6.2) 对位置的写访问大小相同。原子写入应 除了写的那些之外不要改变任何比特除非明确布局 控制(参见分区II(控制实例布局))用于 改变默认行为,数据元素不大于自然 字大小(原生int的大小)应正确对齐。 对象引用应被视为存储在 原生单词大小。
[注意:无法保证原子更新 (读 - 修改 - 写)内存,除了提供的方法 作为类库的一部分的目的(参见Partition IV)。一个原子 写一个“小数据项”(一个不大于原生单词的项目) size)需要在硬件上进行原子读取/修改/写入 不支持直接写入小数据项。结束说明]
[注: 当a的大小时,没有保证对8字节数据的原子访问 native int是32位,即使某些实现可能会执行 数据在8字节边界上对齐时的原子操作。结束 音符]
关于64位长的问题,Eric Lippert在这里回答:http://blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are-different-part-two.aspx
CLI规范实际上提供了更强有力的保证。 CLI 保证读取和写入值类型的变量 处理器的自然指针大小的大小(或更小) 原子;如果您在64位操作系统上运行C#代码 64位版本的CLR然后读取和写入64位双精度和 长整数也保证是原子的。 C#语言可以 不保证,但运行时规范确实如此。 (如果你正在运行C# 某些环境中的代码未被某些人实现 CLI的实现当然你不能依赖它 保证;如果您愿意,请联系卖给您运行时的供应商 知道他们提供什么保证。)
关于原子访问的另一个细微之处在于底层 处理器仅在读取变量时保证原子性 写入与与右侧对齐的存储相关联 记忆中的位置。最终变量将实现为 指向某处内存的指针。在32位操作系统上,那 指针必须可被4整除,才能进行读或写 保证是原子的,并且在64位操作系统上它具有 被8整除。
答案 2 :(得分:6)