要掌握某些技术,您必须知道它是如何在较低的抽象级别上制造的.对于多线程编程,最好了解同步原语。
这是一个问题,如何在.NET中实现Lock(Monitor)?
我被这些方面所吸引:
-它利用OS对象吗?;
-它需要用户模式还是内核模式?;
-等待锁定的线程的开销是多少?;
-在什么情况下线程会排队等待锁?
Updated:
"如果有多个线程争用该锁,它们将在"就绪队列"中排队,并以先到先得的方式授予该锁。注意:windows和CLR行为的细微差别意味着:" [简而言之,C#4.0,约瑟夫·阿尔巴哈里(Joseph Albahari)],这就是我在最后一个关于"违规队列"的问题中所问的问题。
最新回答
- 2021-1-111 #
- 2021-1-112 #
经过一些调查,我找到了问题的答案.总的来说,CodeInChaos和Henk Holterman是正确的,但是这里有一些细节.
当线程首先开始与其他线程争用锁时,它会尝试等待获取一段时间的自旋等待循环.所有这些操作均在user-mode中执行.然后,如果没有成功,则OS内核对象
Event
创建后,线程将切换到内核模式并等待来自此Event
的信号 .所以我的问题的答案是:
1.在更好的情况下,不,但在更坏的情况下, 懒惰地创建对象(如果需要);
2.通常,它在用户模式下工作,但是如果线程争夺锁的时间太长,则可以将线程切换到内核模式(通过win API非托管函数调用);
3.从用户模式切换到内核模式的开销(约1000个CPU周期);
4. Microsoft声称它是类似于FIFO的"诚实"算法,但不能保证这一点. (例如,如果"等待队列"中的线程将被挂起,则线程将在恢复时移至队列末尾。)Event
相关问题
- c#:NET 40和可怕的OnUserPreferenceChanged挂起c#netmultithreadingclrdeadlock2021-01-11 12:56
- c#:获取windows 8自动颜色主题的活动颜色c#netwpfwinapiwindows82021-01-12 01:28
- c#:遍历函数结果时,foreach如何工作?c#netforeach2021-01-11 17:26
- c#:并行执行任务c#netasynchronousasyncawaittaskparallellibrary2021-01-11 04:56
- c#:静态和实例方法同名?c#netoop2021-01-11 05:55
wikipedia文章很好地描述了"监视器"是什么以及其基础技术"条件变量"。
请注意,.NET Monitor是条件变量的正确实现; 大多数已发布的win32 CV实现都是错误的,即使是在知名的来源(例如Dobbs博士)中发现的也是如此.这是因为无法从现有的win32同步原语轻松构建CV。
.NET CV实现不仅利用win32原语构建浅(且不正确)的包装器,还利用了它在.NET平台上,实现其自己的等待队列等事实的优势。