What type of locking mechanism does lock statement use

后端 未结 3 509
生来不讨喜
生来不讨喜 2021-01-18 10:53

Does the c# lock keyword use a \'yielding\', \'spin-locking\' or hybrid approach to handle contention?

So far my searches on the .net lock statement hasn\'t turned u

相关标签:
3条回答
  • 2021-01-18 10:55
    lock (obj)
    {
    }
    

    was just syntactic sugar for Monitor.Enter in a try...finally.

    Monitor.Enter(obj);
    try
    {
    }
    finally
    {
        Monitor.Exit(obj);
    }
    

    It is now something a little better (Thanks to Mark and Adriano for keeping me current).

    bool locked = false;  
    try  
    {  
        Monitor.Enter(_syncRoot, ref locked);  
    }  
    finally  
    {  
        if (locked)  
            Monitor.Exit(_syncRoot);  
    } 
    
    0 讨论(0)
  • 2021-01-18 10:55

    This is Microsoft documentation saying lock() wraps Monitor.Enter/Exit

    "use the C# lock statement, which wraps the Enter and Exit methods in a try…finally block."

    from http://msdn.microsoft.com/en-us/library/de0542zz.aspx

    If you want a spinlock type you can use ReaderWriterLockSlim()

    http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

    0 讨论(0)
  • 2021-01-18 11:08

    Following code:

    lock (_syncRoot)
    {
        // Do stuff
    }
    

    Is translated by the compiler to:

    Monitor.Enter(_syncRoot)
    try
    {
        // Do stuff
    }
    finally
    {
        Monitor.Exit(_syncRoot);
    }
    

    This is the naive (and old) implementation, actually with .NET 4.0 the implementation is more or less this (see Eric's blog for complete reference):

    bool locked = false;
    try
    {
        Monitor.Enter(_syncRoot, ref locked);
    }
    finally
    {
        if (locked)
            Monitor.Exit(_syncRoot);
    }
    

    EDITED

    That said the question is how Monitor.Enter() works? Well, default Mono implementation uses a semaphore to acquire the lock but Microsoft .NET implementation acts different.

    I was reading Concurrent Windows Programming (by Joe Duffy) when a paragraph did catch my attention, my first answer said "no, it doesn't use spinning because performance may not be good in general cases". Correct answer is "yes, .NET Monitor uses spinning". Both .NET Monitor and Windows Critical Sections perform a short spinning before falling back to a true wait on a kernel object. This algorithm is called "two-phase locking protocol" and it's appropriate because context switches and kernel transitions are very expansive, on a multiprocessor machine spinning can avoid both of them.

    Moreover do not forget these are implementation details and can change in any release (or algorithm can be different for different hardwares because of JIT compiler).

    0 讨论(0)
提交回复
热议问题