C# Interlocated.CompareExchange单线程等效代码
我不知道为什么,但我似乎不太明白在C# Interlocated.CompareExchange单线程等效代码,c#,thread-safety,interlocked,C#,Thread Safety,Interlocked,我不知道为什么,但我似乎不太明白在联锁的.compareeexchange(参考inta,intb,intc)中发生了什么 如果它只是简单地在单线程环境中实现,有人能告诉我它将做什么吗 i、 e.用“do that…but as a atomic,thread safe operation”替换什么代码?以下是我对代码的理解(在单线程领域): 摘自此处的文档: 参数 位置1(Int32) 目的地,其值与comparand进行比较并可能被替换 值(Int32) 如果比较结果相等,则替换目标值的值
联锁的.compareeexchange(参考inta,intb,intc)
中发生了什么
如果它只是简单地在单线程环境中实现,有人能告诉我它将做什么吗
i、 e.用“do that…but as a atomic,thread safe operation”替换什么代码?以下是我对代码的理解(在单线程领域): 摘自此处的文档: 参数
- 位置1(Int32)
目的地,其值与comparand进行比较并可能被替换 - 值(Int32)
如果比较结果相等,则替换目标值的值 - 比较数据(Int32)
与位置1处的值进行比较的值 - 返回(Int32)
位置1中的原始值
如果比较符和位置1中的值相等,则该值存储在位置1中。否则,不执行任何操作。比较和交换操作作为原子操作执行。CompareExchange的返回值是位置1中的原始值,无论交换是否发生。在单线程连接中,该代码的意思是(我相信):
如果(a==c){a=b;}
。由于它读取两个操作数,然后作为单个操作的一部分进行写入,因此它自然不是原子的。CompareExchange
调用使其原子化(英特尔体系结构机器有一个原子指令来执行此操作-在其他机器上,它可能涉及某种锁)ref int
不能为空。第一个参数是ref,因为它被读取(作为if
的一部分)并可能被写入。但是,它从来都不是空的。我也认为你的逻辑是错误的。if
条件是正确的,但是代码应该是if(location1==comparand){location1=value;}
Interlocated.CompareeExchange的文档说,如果location1是空指针,它会抛出ArgumentNullException。你说得对,我确实犯了一个错误,但这是一个幼稚的实现@Xtros:它确实(说它抛出)。但是,请尝试编译代码。您将看到警告CS0472:表达式的结果总是“false”,因为类型为“int”的值永远不等于类型为“int”的“null”?
问题的目的是大致了解Interlocated.CompareExchange的功能。如果您愿意,我可以将其更改为伪代码,但这只是一个粗略的概念。提供有关CompareExchange技术性的更多信息。感谢您复制答案。啊,但您在我开始编写代码后编辑了答案。您的原始代码是错误的。@Flydog57谢谢,这帮助您将所有内容都安排妥当。下一个问题是:“这到底是什么返回值!?”()嗯,为什么不是?否则,旧值将丢失。您知道value
和comparand
的值。唯一更改的值是location1
的值。如果你想要的话,把它交回去可以让你保存它。
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;
}
static int CompareExchange(ref int location1, int value, int comparand)
{
var valueToReturn = location1;
if (location1 == comparand)
{
location1 = value;
}
return valueToReturn;
}