Interlocked.CompareExchange 单线程等效代码

Posted

技术标签:

【中文标题】Interlocked.CompareExchange 单线程等效代码【英文标题】:Interlocked.CompareExchange single-threaded equivalent code 【发布时间】:2019-12-17 23:18:22 【问题描述】:

我不知道为什么,但我似乎无法完全理解 Interlocked.CompareExchange(ref int a, int b, int c) 中发生的事情。

如果只是简单地在单线程环境中实现,有人可以告诉我它会做什么吗?

即它用“做那个......但作为原子的、线程安全的操作”替换了什么代码?

【问题讨论】:

在单线程领域,该代码意味着(我相信):if (a == c) a = b; 。由于它读取两个操作数,然后作为单个操作的一部分进行写入,因此它自然不是原子的。 CompareExchange 调用使其具有原子性(英特尔架构机器有一个原子指令来执行此操作 - 在其他机器上,它可能涉及某种锁定) 【参考方案1】:

这是我对代码的理解(在单线程领域):

static int CompareExchange(ref int location1, int value, int comparand)

    var valueToReturn = location1;
    if (location1 == comparand)
    
        location1 = value;
    

    return valueToReturn;

取自此处的文档:https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.compareexchange

参数

location1 (Int32) 目的地,其值与比较值进行比较并可能被替换。 值 (Int32) 如果比较结果相等,则替换目标值的值。 比较 (Int32) 与 location1 处的值进行比较的值。 返回 (Int32) location1 中的原始值。

备注

如果comparand 与location1 中的值相等,则将value 存储在location1 中。否则,不执行任何操作。比较和交换操作作为原子操作执行。无论是否发生交换,CompareExchange 的返回值都是 location1 中的原始值。

【讨论】:

感谢您复制答案。 啊,但是自从我开始编写代码以来,您就编辑了答案。您的原始代码错误。 @Flydog57 谢谢,这帮助一切就位。下一个问题是:“为什么是返回值!?” (***.com/questions/59388171/…) 呃,为什么不呢?否则旧值将丢失。你知道valuecomparand 的值。唯一改变的值是location1 的值。如果您愿意,可以将其交还给您。【参考方案2】:
int CompareExchange(ref int location1, int value, int comparand)

    if (location1 == null)
        throw new ArgumentNullException(nameof(location1));

    if (location1 != comparand)
    
        return location1;
    

    int originalValue = location1;
    location1 = value;
    return originalValue;

【讨论】:

A ref int 不能为空。第一个参数是 ref,因为它被读取(作为if 的一部分)并且可能被写入。但是,它永远不会为空。我也认为你的逻辑是错误的。 if 条件是正确的,但代码应该只是 if (location1 == comparand) location1 = value; Interlocked.CompareExchange 的文档说如果 location1 是空指针,它会抛出 ArgumentNullException。你是对的,我确实有一个错误,但这是一个幼稚的实现。 ;) @Xtros:确实如此(说它抛出)。但是,请尝试编译您的代码。你会得到warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?' 这个问题的目的是大致了解 Interlocked.CompareExchange 的作用。如果您愿意,我可以将其更改为伪代码,但这是其作用的粗略概念。 This question 提供了有关 CompareExchange 技术性的更多信息。

以上是关于Interlocked.CompareExchange 单线程等效代码的主要内容,如果未能解决你的问题,请参考以下文章