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/…) 呃,为什么不呢?否则旧值将丢失。你知道value
和comparand
的值。唯一改变的值是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;
【讨论】:
Aref 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 单线程等效代码的主要内容,如果未能解决你的问题,请参考以下文章