写一个答案 另一个问题 一些有趣的事情出来了,现在我无法理解 Interlocked.Increment(ref long value)
适用于32位系统。让我解释。
本地人 InterlockedIncrement64
现在在编译32位环境时不可用,好吧,这是有道理的,因为在.NET中你不能根据需要对齐内存,它可能从 管理 然后他们放弃了。
在.NET中我们可以调用 Interlocked.Increment()
在引用64位变量时,我们对其对齐没有任何限制(例如在结构中,我们也可以使用 FieldOffset
和 StructLayout
)但文档没有提到任何限制(AFAIK)。这很神奇,它有效!
汉斯帕斯特指出 Interlocked.Increment()
是一个 特别 JIT编译器识别的方法,它将发出一个调用 COMInterlocked :: ExchangeAdd64() 然后会打电话 FastInterlockExchangeAddLong 这是一个宏 InterlockedExchangeAdd64 分享相同 限制 的 InterlockedIncrement64。
现在我很困惑。
忘记一秒钟的托管环境,然后回到本地。为什么 InterlockedIncrement64
不能工作但是 InterlockedExchangeAdd64
呢? InterlockedIncrement64
如果内在函数不可用,则是一个宏 InterlockedExchangeAdd64
然后它可以实现为调用 InterlockedExchangeAdd64
...
让我们回到托管:如何在32位系统上实现原子64位增量?我猜是句 “这个函数是原子的 关于调用其他互锁功能“ 很重要,但我仍然没有看到任何代码(感谢Hans指出更深入的实现)来做到这一点。我们来挑选 InterlockedExchangedAdd64
当内在函数不可用时,从WinBase.h实现:
FORCEINLINE
LONGLONG
InterlockedExchangeAdd64(
_Inout_ LONGLONG volatile *Addend,
_In_ LONGLONG Value
)
{
LONGLONG Old;
do {
Old = *Addend;
} while (InterlockedCompareExchange64(Addend,
Old + Value,
Old) != Old);
return Old;
}
如何读/写原子?