c# - 在.NET中锁定(监视)内部实现




multithreading synchronization (2)

维基百科的文章很好地描述了“监视器”是什么,以及它的基础技术,条件变量。

请注意,.NET Monitor是条件变量的正确实现; 大多数已发布的CV的Win32实现都是不正确的,即使是在Dobbs博士等通常有信誉的来源中也是如此。 这是因为无法从现有的Win32同步原语轻松构建 CV。

.NET CV实现不仅仅是在Win32原语上构建一个浅(且不正确)的包装器,而是利用它在.NET平台上实现自己的等待队列等事实。

掌握一些技术,你必须知道它是如何在一个抽象级别下制作的。 在多线程编程的情况下,了解同步原语将是一件好事。
这是一个问题,如何在.NET中实现Lock(Monitor)?

我对这些问题很感兴趣:
- 它是否使用OS对象?
- 它需要用户模式还是内核模式?
- 等待锁定的线程的开销是多少?
- 在什么情况下,等待锁的线程队列可能会被违反?

更新:
“如果多个线程争用锁定,它们就会在”就绪队列“中排队,并按照先到先得的原则授予锁定。 注意:Windows和CLR行为的细微差别意味着公平性队列有时可能会被违反。 “[C#4.0 in a Nutshell,Joseph Albahari]所以这就是我在关于'违规队列'的最后一个问题中所要求的。


经过一些调查后,我找到了问题的答案。 一般来说,CodeInChaos和Henk Holterman是对的,但这里有一些细节。

当线程开始首先争夺与其他线程的锁时,它会尝试旋转等待循环一段时间以获取锁定。 所有这些操作都在用户模式下执行。 然后,如果OS内核对象Event没有成功创建,则线程切换到内核模式并等待来自此Event信号。

所以回答我的问题是:
1.更好的情况是没有,但更糟糕的是( Event对象懒惰地创建,如果需要);
2.一般情况下它在用户模式下工作,但如果线程争用锁的时间太长,则可以将线程切换到内核模式(通过Win API非托管函数调用);
3.从用户模式切换到内核模式的开销(~1000个CPU周期);
微软声称它是像“FIFO”这样的“诚实”算法,但并不能保证这一点。 (例如,如果来自“等待队列”的线程将被暂停,它将在恢复时移动到队列的末尾。)







monitor