开发者

How does System.Threading.Monitor.Enter() work?

开发者 https://www.devze.com 2023-03-22 07:28 出处:网络
I got a question how Monitor.Enter works. I investigated .net framework source code, and it shows this only:

I got a question how Monitor.Enter works. I investigated .net framework source code, and it shows this only:

    [System.Security.SecurityCritical]  // auto-generated 
    [ResourceExposure(ResourceScope.None)] 
    [MethodImplAttribute(MethodImplOptions.InternalCall)] 
    private static extern void ReliableEnter(Object obj, ref bool lockTaken);

I guess Monitor.Enter implementation is platform dependent, so I browsed Mono source code and I gave up :(

Yes, a critical section assigned for each System.Object instance may solve, but, I don't think the actual Monitor.Lock is written like this, because creating a critical section for each System.Object will cost unlimitedly. (Win32 does not allow billions of critical sect开发者_运维问答ion objects in a process!)

Does anybody know how Monitor.Enter works? Please reply. Thanks in advance.


Every object in .NET has two extra (hidden—you can't see them) overhead members:

  • A "type object pointer". This is just a reference to the Type instance of the object. In fact, you can "access" this by calling GetType().
  • A "sync block index". This is a native WORD size integral type which is an index into the CLR's internal array of "Sync Blocks".

This is how it keeps track of which objects are locked.

The Sync Block structure contains a field that can be marked for locking. Basically, when you lock an object, this field is switched on. When the lock is released, it is switched off (basically - I haven't looked at the SSCLI for long enough to delve deeper into how that sort of operation works - I believe it is based on EnterCriticalSection though..).

The MethodImplOptions.InternalCall arguments you've passed to the attribute above means that the actual implementation of that method resides in the CLR.. which is why you can't browse any further through the code.


Looking at the Mono source code, it seems that they create a Semaphore (using CreateSemaphore or a similar platform-specific function) when the object is first locked, and store it in the object. There also appears to be some object pooling going on with the semaphores and their associated MonoThreadsSync structures.

The relevant function is static inline gint32 mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_interruption) in the file mono/metadata/monitor.c, in case you're interested.

I expect that Microsoft .Net does something similar.


Microsoft .NET - whenever possible - tries a spinlock on the thin lock structure in the object header. (Notice how one can "lock" on any object.)

Only if there is a need for it will an event handle be used from the pool or a new one allocated.

0

精彩评论

暂无评论...
验证码 换一张
取 消