Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What type of locking mechanism does lock statement use

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 up an answer. I will post if I do find any more. So far all I could find is When should one use a spinlock ... with a nicely worded accepted answer by Mecki.

But I am looking for some definitive answer or documentation regarding .net/c# if anyone has one.

like image 917
Vort3x Avatar asked Jul 06 '12 12:07

Vort3x


People also ask

What is lock statement?

The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

What is a locking mechanism?

A locking mechanism is a mechanical system which provides assistance to the coupling and uncoupling of two connectors and the fixation of the two parts in operating position. The locking system helps to maintain the primary function of electrical continuity and is involved in the sealing performances of products.

Why lock is used in threading?

A lock may be a tool for controlling access to a shared resource by multiple threads. Commonly, a lock provides exclusive access to a shared resource: just one thread at a time can acquire the lock and everyone accesses to the shared resource requires that the lock be acquired first.


1 Answers

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).

like image 110
Adriano Repetti Avatar answered Sep 23 '22 16:09

Adriano Repetti