C#中哪些操作是原子的?

时间:2012-07-31 17:10:06

标签: c# .net multithreading atomic

是否有系统的方法来了解C#中的操作是否是原子操作?或者是否有任何一般指导方针或经验法则?

3 个答案:

答案 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)

根据CLI规范,您可以获得here

  

“符合标准的CLI应保证对其的读写访问权限   正确对齐的内存位置不大于本机字大小   (native int类型的大小)是原子的......“

C#规范的第12.5节here

  

“以下数据类型的读写应该是原子的:bool,   char,byte,sbyte,short,ushort,uint,int,float和reference   类型。“另外:”......不保证原子读 - 修改 - 写,   例如在增加或减少的情况下。“

使用this使增量操作成为原子。

相关问题