C# NET中的锁(监视器)内部实现

C# NET中的锁(监视器)内部实现,c#,.net,multithreading,synchronization,monitor,C#,.net,Multithreading,Synchronization,Monitor,为了掌握某些技术,你必须知道它是如何在一个较低的抽象级别上实现的。对于多线程编程,最好了解同步原语。 问题是,如何在.NET中实现锁(监视器) 我对这几点很感兴趣: -它是否利用操作系统对象 -它需要用户模式还是内核模式 -等待锁定的线程的开销是多少 -在什么情况下,等待锁定的线程队列可能被违反 更新: “如果有多个线程争用锁,它们将在“就绪队列”上排队,并根据先到先得的原则授予锁。注意:Windows和CLR行为的细微差别意味着有时可能会违反队列的公平性。”[C#4.0简言之,Joseph A

为了掌握某些技术,你必须知道它是如何在一个较低的抽象级别上实现的。对于多线程编程,最好了解同步原语。
问题是,如何在.NET中实现锁(监视器)

我对这几点很感兴趣:
-它是否利用操作系统对象
-它需要用户模式还是内核模式
-等待锁定的线程的开销是多少
-在什么情况下,等待锁定的线程队列可能被违反

更新:
“如果有多个线程争用锁,它们将在“就绪队列”上排队,并根据先到先得的原则授予锁。注意:Windows和CLR行为的细微差别意味着有时可能会违反队列的公平性。”[C#4.0简言之,Joseph Albahari]这就是我在上一个关于“违反队列”的问题中所问的问题。

对“监视器”是什么以及它的底层技术条件变量有很好的描述

请注意,.NET监视器是条件变量的正确实现;大多数已发布的Win32 CVs实现都是不正确的,即使是在Dobbs博士等通常声誉良好的来源中也可以找到。这是因为一份简历


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

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

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

所以我的问题的答案是:
1.在较好的情况下为否,但在较差的情况下为是(
事件
对象在需要时延迟创建)
2.一般来说,它在用户模式下工作,但如果线程争夺锁的时间过长,线程可以切换到内核模式(通过WinAPI非托管函数调用)
3.从用户模式切换到内核模式的开销(约1000个CPU周期)

4.微软声称它是像FIFO一样的“诚实”算法,但它不能保证这一点。(例如,如果“等待队列”中的线程将被挂起,它将在恢复时移动到队列的末尾。)

否,用户,无论获取锁需要多长时间,都不知道“违反的队列”是什么样子。试着提出一个更好的问题。如果我没记错的话,它会尝试旋转一段时间,如果这不起作用,它就会返回内核。因此,如果锁没有被争用,那么成本就相当低,但对于高锁争用,成本可能会更高。这是否意味着关键部分在后台使用?而使用.NET4.0则更为正确。如果在
监视器之后出现异常,则锁可能仍然“卡住”。请输入
(参见此)如果希望在Win32中使用条件变量,请使用Windows V6(Vista/2008)中引入的操作系统实现:@Richard:谢谢您的提示!我不知道他们是在Win32级别引入的。你的Wikipedia链接没有回答任何问题,问题的最重要部分是内核与用户模式。。。那篇文章是另一篇关于聪明的文章,你能为你的研究发表一些资料吗?这将是有帮助的。我希望看到第1条和第2条陈述的详细解释。我想知道.NET何时决定在监视器实现中进入内核模式这在Clr中通过C#详细讨论过,Jeffrey Richter称之为“混合锁”。在用户模式下,monitor会旋转并与其他线程竞争(因为它们没有被阻止),一旦它们升级到内核模式锁,它们就会被阻止,从而释放周期。