And*_*ell 5 .net c# multithreading language-design framework-design
有人可以详细解释为什么lock在C#中对任何类型的对象都有可能吗?
我理解它是什么lock以及如何使用它.我知道它如何扩展到Monitor.Enter/ Exit.我正在寻找实施细节和设计考虑因素的解释.
首先:引擎盖下发生了什么?例如:对象实例中是否有额外的位(就像RTTI/vtable那样)可以使它工作?或者在对象引用上键入某种查找表?(如果是这样,它如何与GC交互?)或其他什么?为什么我不必创建一个特定类型的实例来保存锁定数据?
(顺便说一下,在本机代码中做什么Enter和Exit映射到什么?)
其次,为什么 .NET设计为没有特定类型来取出锁定?(鉴于你通常只new object()为了这个目的而制作一个- 而且你锁定"任何旧对象"的大多数情况都是有问题的.)这个设计选择是否被实现细节强迫了?还是故意的?而且,如果是故意的,这是一个不错的选择吗?(我意识到第二部分可能需要推测.)
可以在lock所有非struct类型上。在堆上每个引用类型的布局中,都有一个特殊字段(同步块)用于管理锁。CLR 如何创建运行时对象中详细介绍了布局。文章摘录如下:
OBJECTREF 并不指向对象实例的开头,而是指向 DWORD 偏移量(4 个字节)。DWORD 称为对象标头,并保存 SyncTableEntry 表的索引(从 1 开始的syncblk 编号)。
对象在堆上的布局:
sync block index
pointer to type
fields...
Run Code Online (Sandbox Code Playgroud)
推测部分:我相信最初的指导是锁定任何方便的东西,但由于很容易让外部代码使您的方法陷入死锁,因此它很快就更改为具有特殊的“用于锁定的私有对象”。我认为框架中甚至有一些类是通过锁定公开可见的对象来实现的......