我想编译使显示器进入内核模式/使用内核同步对象的所有可能情况的列表。
同步块有一个字段引用内核对象,因此我减除lock
会去到内核模式的某个时候。
我发现这一点: 在.NET锁(监视器)内部实现
但它有太多的问题需要回答,唯一有用的信息是,OP通过简单地说明该回答了自己的问题lock
将进入内核模式的某个时候。 也有是什么支撑这个答案没有任何联系。
我的问题是不同的- 我想知道确切时间lock
会去到内核模式 (如果没有,不为什么-时)。
我更感兴趣地听到有关.NET 4和4.5是否存在与旧版本有什么区别
编辑:从里氏书:“一个同步块包含一个内核对象领域,拥有线程的ID,递归数和等待的线程数。”
大多数这些类型的问题,可以通过查看作为可通过CLR的源代码来回答SSCLI20分布 。 它是由现在变得有点过时,它是.NET 2.0的年份,但很多核心CLR功能都没有太大的变化。
你想看看源代码文件是CLR / src目录/ VM / syncblk.cpp。 三个班在这里发挥作用,AwareLock是低级别的锁实现,需要获取锁的照顾,同步块是实现正在等待进入一个锁的线程队列中的类,CLREvent是操作系统同步包装对象,你问的是一个。
这是C ++代码和抽象的水平是相当高的,这大量的代码与垃圾收集器交互,有很多的测试代码包括在内。 所以,我给过程的简要说明。
同步块具有存储AwareLock实例m_Monitor成员。 同步块:: Enter键()直接调用AwareLock :: Enter键()。 它首先会尝试尽可能便宜获取锁。 首先检查是否线程已经拥有的锁,只是增加锁定计数,如果是这样的话。 使用FastInterlockCompareExchange(),内部功能非常类似于Interlocked.CompareExchange下一步()。 如果锁不发生竞争那么这种成功非常迅速,Monitor.Enter()返回。 如果没有,那么另一个线程已经拥有该锁,用于AwareLock :: EnterEpilog。 有必要涉足操作系统的线程调度器,以便使用CLREvent。 它是动态如果需要创建,其WaitOne的()方法被调用。 这将涉及到内核的过渡。
所以,有足够的回答你的问题:Monitor类进入内核模式下,当锁定发生冲突和线程必须等待。
当锁争用巨资。
如果锁轻轻主张,有一个快速的CPU自旋锁等待锁再次是免费的,但如果不等待足够长的锁是自由的,该线程将互斥阻塞等待,它涉及内核模式呼叫挂起线程等这样的管理。
后其spinwait一步。
附加的智能可能存在,例如跳单核的机器spinwait因为有争议锁只能释放线程后公布。