在c#中,Interlocked类中是否有锁或队列?

时间:2014-07-29 13:35:02

标签: c# multithreading concurrency

Interlocked.Increment

Increments a specified variable and stores the result, as an atomic operation.

所以这意味着当多个线程同时调用它时,结果也是正确的。

但是我还在询问它是如何实现这一点的。当两个线程同时调用它时,它们之间是否有顺序?例如,一个线程首先调用它,另一个线程调用它。像队列一样。

我的意见是对的吗?

2 个答案:

答案 0 :(得分:4)

抖动具有对此类方法的特定意识。必要的是因为它们的实现是高度特定于处理器的。

对于x86和x64抖动,它将使用LOCK XADD机器代码指令替换方法调用。英特尔处理器上可用的特定指令,用于原子递增变量。一个极端情况是在 long 类型的变量上使用它,在32位模式下,抖动生成对CLR内部的辅助方法的调用以完成工作。命名为COMInterlocked::ExchangeAdd64()。而后者又使用汇编代码来使用x86处理器上提供的LOCK CMPXCHG8B机器代码指令。它将是ARM或Itanium处理器上的其他产品,我没有随时可以查看的内容。

您可以通过使用Debug + Windows + Disassembly调试器窗口查看生成的机器代码来自行发现这些详细信息。

答案 1 :(得分:2)

内部Interlocked.Increment的内容是实现细节。不同的实现(.Net 2与.Net 4.5与Mono2等)可能会完全不同。

E.g。 MS .Net实现(在Windows上)将使用归结为InterlockedExchangeAdd调用IIRC的内容,但这是一个实现细节,可能会发生变化。

如何实现InterlockedExchangeAdd是Windows内核的一个细节,可能因版本,平台或平台或两者而异。例如。 Windows可能以某种形式使用Raymond Chen describes some possible implementations(是的,复数:实现)。它通常是某种形式的LS/SC和/或CAS(抛出一些内存障碍以获得良好的衡量标准),这些形式被认为是无锁的,可能取决于实际CPU的实现细节。

E.g。 mono可以使用a pthread_mutex或Windows Interlocked* API或内存条等...取决于您构建单声道的操作系统和平台。这是您不应该依赖的实施细节。未来的单声道版本可以使用其他东西然后,即使pthread_mutex也有多个实现,你猜对了,它们在未来的任何时候都会发生变化。