.Net CompareExchange重新排序

omi*_*nug 6 .net c# multithreading test-and-set memory-fences

编译器或处理器可以重新排序以下指令,以便另一个线程看到a == 0b == 1

假设int a = 0, b = 0;某个地方.

System.Threading.Interlocked.CompareExchange<int>(ref a, 1, 0);
System.Threading.Interlocked.CompareExchange<int>(ref b, 1, 0);
Run Code Online (Sandbox Code Playgroud)

Ono*_*osa 5

Interlock不会.使用将发出完整的记忆围栏信号."也就是说,任何变量在Interlocked方法调用之前写入方法之前执行Interlocked,并且在调用之后执行调用之后读取任何变量."[1]他们使用易失性读/写方法来阻止b = 1之前的操作a = 1.

[1]:Jeffrey Richter:"通过C#的CLR - 第三版"第V部分,第803页

  • @Servy我看不出那可能是真的,或者`lock`的行为会崩溃."lock"的正确功能取决于阻止读取和写入在其子块之外重新排序的障碍,并且这些读取和写入通常与锁定目标不在同一位置. (2认同)
  • @MikeStrobel这假设两个工具都使用相同的同步机制.`lock`具有不同的,更严格的同步机制,用于强制执行其行为. (2认同)
  • @Servy clr 内存模型不是我的强项(在我看来,我上次检查时它的记录也严重不足) - JMM 是。但据我所知,可以保证互锁指令包含完整的内存屏障(不过,获取/释放对我们来说就足够了),这保证了禁止重新排序。 (2认同)