40

For mastering of some technology you have to know how it's made at one abstraction level lower. In case of multithreading programming, it will be good to know about synchronization primitives.
Here is the question, how implemented Lock (Monitor) in .NET?

I'm intrested in such points:
- does it utilize OS objects?;
- does it require user mode or kernel mode?;
- what is overhead for threads that are waiting for lock?;
- in what cases threads queue that awaiting for the lock could be violated?.

Updated:
"If more than one thread contends the lock, they are queued on a “ready queue” and granted the lock on a first-come, first-served basis. Note: Nuances in the behavior of Windows and the CLR mean that the fairness of the queue can sometimes be violated." [C# 4.0 in a Nutshell, Joseph Albahari] So this is what I'm asking about in last question concerning 'violated queue'.

alexber
  • 647
  • 1
  • 5
  • 9
  • 2
    No, user, however long it takes to acquire the lock, no idea what a "violated queue" looks like. Try to formulate a better question. – Hans Passant Feb 24 '11 at 23:27
  • 3
    If I recall correctly it tries spinning for a while, and if that doesn't work it yields back to the kernel. So it's rather cheap if the lock isn't contended, but can become more expensive for high lock contention. – CodesInChaos Feb 24 '11 at 23:33
  • 1
    This behavior is looks like the same as for Critical Section in Windows. Does it mean that Critical Section utilize in background? – alexber Feb 25 '11 at 14:51

2 Answers2

23

The Wikipedia article has a pretty good description of what a "Monitor" is, as well as its underlying technology, the Condition Variable.

Note that the .NET Monitor is a correct implementation of a condition variable; most published Win32 implementations of CVs are incorrect, even ones found in normally reputable sources such as Dr. Dobbs. This is because a CV cannot easily be built from the existing Win32 synchronization primitives.

Instead of just building a shallow (and incorrect) wrapper over the Win32 primitives, the .NET CV implementation takes advantage of the fact that it's on the .NET platform, implementing its own waiting queues, etc.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • 5
    And with .NET 4.0 it's even more correct. There was the possibility of having a lock remaining "stuck" if there was an exception just after the `Monitor.Enter` (see this http://stackoverflow.com/questions/2837070/lock-statement-vs-monitor-enter-method/2837224#2837224) – xanatos Feb 25 '11 at 05:48
  • 3
    If you want a condition variable in Win32 then use the OS implementation that was introduced with Windows V6 (Vista/2008): http://msdn.microsoft.com/en-gb/library/ms682052(VS.85).aspx – Richard Feb 28 '11 at 17:26
  • @Richard: Thanks for the tip! I didn't know they introduced this at the Win32 level. – Stephen Cleary Feb 28 '11 at 18:01
  • 2
    your Wikipedia link doesn't answer anything, the most important part of the question is kernel vs user mode... that article is another blob of cleverness for cleverness sake – Boppity Bop Feb 17 '13 at 14:51
20

After some investigations I've found out answers to my questions. In general CodeInChaos and Henk Holterman were right, but here is some details.

When thread start to contends for a lock with other threads firstly it it does spin-wait loop for a while trying to obtain lock. All this actions performs in user-mode. Then if no success OS kernel object Event creates, thread is switched to the kernel-mode and waits for signal from this Event.

So answer to my questions are:
1. In better case no, but in worse yes (Event object lazily creates if required);
2. In general it works in user-mode but if threads compete for a lock too long, thread could be switched to kernel-mode (via Win API unmanaged function call);
3. Overhead for switch from user-mode to kernel-mode (~1000 CPU cycles);
4. Microsoft claim that it is "honest" algorithm like FIFO but it doesn't guarantee this. (E.g. If thread from 'waiting queue' will be suspended it moves to the end of queue when it would be resumed.)

alexber
  • 647
  • 1
  • 5
  • 9
  • 13
    Can you post any sources for your research? That would be helpful – devshorts Sep 23 '12 at 20:38
  • 2
    I would like to see the detailed explanation of the 1 and 2 statements. I want to know when exactly .NET decides to go to kernel-mode in the Monitor implementation – Boppity Bop Feb 17 '13 at 15:07
  • 3
    This is discussed in length in Clr Via C#, Jeffrey Richter calls it a "hybrid lock". In user mode, monitor spins and competes with other threads (as they are not blocked), once they get promoted to kernel mode locks they get blocked thus freeing cycles. – Rohit Sharma Jan 23 '14 at 14:02