【问题标题】:Int64 (long) and Thread SafetyInt64(长)和线程安全
【发布时间】:2010-08-02 02:42:00
【问题描述】:

来自 MSDN 的引述

在所有硬件平台上分配这种类型的实例并不是线程安全的,因为该实例的二进制表示可能太大而无法在单个原子操作中分配。

这是否意味着 Thead 在 64 位处理器(如 Itianium 或 x86-64)上也是安全的?

例如:

long data = GetData();
// some parallel task on data

可能是个问题?

【问题讨论】:

标签: c# multithreading msdn


【解决方案1】:

可能,但是您为什么要编写一个在某些类似英特尔工作的平台上是线程安全的程序,而在其他平台上却不是呢?请注意,DecimalDouble 类型也有关于线程安全的免责声明。

Microsoft 建议在这些情况下使用锁。这里有一些关于并发、内存映射和低级锁的好信息的链接:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f03ea3c9-4c2b-4a79-8f8c-4a6b7476b20d

【讨论】:

    【解决方案2】:

    如果内存加载/存储操作是在内存块上执行的,这些内存块位于对齐的内存地址上并且不大于本机机器大小的指针。
    这意味着,在 64 位对齐内存地址上的加载/存储操作在 64 位平台上将是原子的,但在 32 位平台上不会是原子的。

    现代处理器提供了一组特殊的指令(在 .Net 中,大部分指令通过 Interlocked 类公开)。允许在大于机器的本机指针大小的加载/存储操作上实现原子性(32 位处理器上的 64 位操作,以及 64 位处理器上的 128 位操作。后者不被 Interlocked 类公开,但在本机代码)。

    更多详情,请查看 Joe Duffy 的帖子:Thread-safety, torn reads, and the like

    【讨论】:

    【解决方案3】:

    如果您的data 变量被不同线程的代码直接访问,就会出现问题。

    他们不对任何特定系统做出保证,所以为了安全起见,我认为它在 x64 系统和 x86 上都不是线程安全的,尽管我怀疑他们真正想到的是运行紧凑框架之类的地方智能手机。

    【讨论】:

    • 但是 int32 没有这个注释,它必须与架构相关 (x64 x86)
    【解决方案4】:

    为了安全起见,我会犯错并假设不会。

    注意this 上一个问题。本质上,对于 Int64 的原子分配,您应该考虑使用 Interlocked 类。

    查看this link 以获得更详细的分析。特别是,请查看标有“原子性和互锁”的部分。

    【讨论】:

      【解决方案5】:

      这里问题的症结在于Int64保证 是原子的,但这并不排除它在某些情况下是原子的。换句话说,Int64 在 64 位系统上是原子的。当然,这并不意味着它一定是线程安全的。除了原子性之外,还有其他关于线程安全的问题。例如,为了防止过时问题,您必须使用适当的内存屏障指令(volatileThread.VolatileWrite 等)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        • 2014-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多