lock语句使用什么类型的锁定机制

c#lock关键字是否使用“让步”,“自旋锁定”或混合方法来处理争用?

到目前为止,我对.net锁定语句的搜索没有找到答案。 如果我找到了,我会发布。 到目前为止,我所能找到的是什么时候应该使用一个自旋锁…用Mecki接受的措辞很好。

但我正在寻找关于.net / c#的一些明确的答案或文件,如果有人的话。

以下代码:

lock (_syncRoot) { // Do stuff } 

由编译器翻译为:

 Monitor.Enter(_syncRoot) try { // Do stuff } finally { Monitor.Exit(_syncRoot); } 

这是天真的(和旧的)实现,实际上使用.NET 4.0实现或多或少这个(请参阅Eric的博客以获得完整的参考):

 bool locked = false; try { Monitor.Enter(_syncRoot, ref locked); } finally { if (locked) Monitor.Exit(_syncRoot); } 

EDITED

那说问题是Monitor.Enter()如何工作? 好吧,默认的Mono实现使用信号量来获取锁,但Microsoft .NET实现的行为不同。

当一个段落引起我的注意时,我正在阅读并发Windows编程 (由Joe Duffy 编写 ),我的第一个回答说“不,它不使用旋转,因为在一般情况下性能可能不好”。 正确答案是“是的,.NET Monitor使用旋转”。 .NET Monitor和Windows Critical Sections在回退到内核对象的真正等待之前执行短暂旋转。 这种算法被称为“两阶段锁定协议”,它是合适的,因为上下文切换和内核转换是非常广泛的,在多处理器上,旋转可以避免它们。

此外,不要忘记这些是实现细节,并且可以在任何版本中进行更改(或者由于JIT编译器,算法对于不同的硬件可能会有所不同)。

 lock (obj) { } 

只是Monitor的语法糖。 最后输入 …

 Monitor.Enter(obj); try { } finally { Monitor.Exit(obj); } 

现在好一点 (感谢马克和阿德里亚诺让我保持最新状态)。

 bool locked = false; try { Monitor.Enter(_syncRoot, ref locked); } finally { if (locked) Monitor.Exit(_syncRoot); } 

这是Microsoft文档说lock()包装Monitor.Enter / Exit

“使用C#lock语句,它将try和Exit方法包装在try … finally块中。”

来自http://msdn.microsoft.com/en-us/library/de0542zz.aspx

如果你想要一个自旋锁类型,你可以使用ReaderWriterLockSlim()

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx