【问题标题】:C# atomicity: assignment of int vs. long on x64 platformC# 原子性:在 x64 平台上分配 int 与 long
【发布时间】:2012-09-18 23:33:44
【问题描述】:

我在看http://msdn.microsoft.com/en-us/library/aa691278(VS.71).aspx,它说int的读写是原子的,而long的读写可能不是。对于 64 位平台真的是这样吗?是不是 IntPtr.Size == 64 位或长?我是否遗漏了什么或语言规格不够完整?

这里还有更多想法: http://philosopherdeveloper.wordpress.com/2011/02/08/beware-assignment-atomic-assignment/

【问题讨论】:

  • 看看这个 - stackoverflow.com/questions/881820/… - 对齐很重要。
  • 您在使用 C# 1.0 和 .NET 1.1 吗?如果没有,那么您可能应该忽略这样的古代文献。规范位于go.microsoft.com/fwlink/?LinkId=199552
  • @JohnSaunders:我刚刚用谷歌搜索了它。您认为不同版本的 .NET 的 C# 语言规范变化很大吗?
  • C# 语言规范在 C# 版本之间发生变化。它与 .NET 版本无关。

标签: c# .net multithreading pointers thread-safety


【解决方案1】:

long 是在具有 64 位字的 CPU 平台上的原子写入。例如如果您在 64 位计算机上运行 32 位 .NET 应用程序,写入 long不是原子的。

请注意,如果您不能确保编译器不会优化对该类型变量的访问,那么原子性几乎毫无意义。例如你不能用volatile 装饰long 字段。

对 64 位字段的操作只能在 64 位运行时环境中保证是原子操作

http://www.albahari.com/threading/part4.aspx

如果您在 64 位版本的 CLR 中在 64 位操作系统上运行 C# 代码,那么 64 位双精度和长整数的读写也保证是原子的

http://blogs.msdn.com/b/ericlippert/archive/2011/05/31/atomicity-volatility-and-immutability-are-different-part-two.aspx

【讨论】:

  • 啊!这就是问题所在。谢谢!这些信息的来源是什么?
  • @Schultz9999 我添加了一些详细说明相同信息的引用和参考资料。
  • “long 是在具有 64 位字的 CPU 和平台上的原子写入” - 这并不完全正确,可能存在例外情况。 1. AFAIK 无法保证编译器永远不会将 64 位 mov 拆分为两个 32 位。 C# 规范不要求 64 位操作的原子性。 2. 即使 CPU 本身也不保证原子性,例如如果两个 32 位部分被拆分到不同的高速缓存行。这些是非常罕见的例外,但也应予以考虑。
  • @valiano 在 32 位处理器或 32 位目标上是正确的,但不是在 64 位处理器上以 64 位处理器为目标
  • 谢谢@PeterRitchie - 我正在查看 C# 规范,但错过了 CLI 规范确保 64 位访问是原子的(其中本机 int 是 64 位)这一事实,如引用中所述博客文章。干杯
【解决方案2】:

这是 VS2003 的文档,它对应于 .NET Framework 1.1,它仅提供 32 位版本(暂时忽略非常小众的 IA-64 版本)。

.NET Framework 2.0 引入了 x64 版本,其中(只要您在 64 位模式下运行)那么某些(但不是全部)Int64 操作将是原子的。

当然,如果您想确定,请使用Interlocked 类。

【讨论】:

    猜你喜欢
    • 2011-05-08
    • 1970-01-01
    • 2011-11-27
    • 2012-01-27
    • 2019-06-15
    • 2017-02-21
    • 1970-01-01
    • 2021-06-25
    • 2017-06-11
    相关资源
    最近更新 更多