2012-07-06 32 views
6

c#lock關鍵字是否使用'yielding','spin-locking'或混合方法來處理爭用?鎖語句使用什麼類型的鎖定機制

到目前爲止,我在.net鎖定語句中的搜索沒有找到答案。 我會發布,如果我找到任何更多。 到目前爲止,我所能找到的是When should one use a spinlock ...,其中有一個措辭很好的Mecki接受的答案。

但是我正在尋找一些關於.net/c#的明確答案或文檔,如果任何人有一個。

回答

9

以下代碼:

lock (_syncRoot) 
{ 
    // Do stuff 
} 

是由編譯器翻譯爲:

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

這是天真的(老)的實施,實際上與.NET 4.0中實現更或更少(參見Eric's blog以供參考):

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

EDITED

認爲問題是如何作品Monitor.Enter()那麼,默認的Mono實現使用信號量來獲取鎖,但是Microsoft .NET的實現行爲不同。

我讀併發Windows程序設計(喬·達菲)當段的確引起我的注意,我的第一個回答說:「沒有,它不使用紡紗,因爲性能可能不是在一般情況下好。」正確答案是「是的,.NET Monitor使用旋轉」。 .NET Monitor和Windows Critical Sections都會在回退到真正的內核對象等待之前執行短暫旋轉。這種算法被稱爲「兩階段鎖定協議」,因爲上下文切換和內核轉換非常廣泛,所以在多處理器機器上可以避免這兩種情況。

此外不要忘記這些是實現細節,可以在任何版本中更改(或者由於JIT編譯器,算法對於不同的硬件可能會有所不同)。

1
lock (obj) 
{ 
} 

只是Monitor的語法糖。 Enter在一個嘗試...最後。

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

現在是東西little better(感謝馬克和阿德里亞諾保持我目前的)。

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

沒有在最近的編譯器版本,它不是 – 2012-07-06 12:35:42

+0

@MarcGravell所以我只注意到。剛剛花了最後10分鐘閱讀FAIC :) – DaveShaw 2012-07-06 12:39:25

0

這是微軟的文檔說鎖()包裝Monitor.Enter /退出

「使用C#lock語句,它包裝的輸入和退出方法嘗試... finally塊。「

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

如果你想要一個自旋鎖類型,你可以使用ReaderWriterLockSlim()

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

+0

爲什麼downvote這個沒有評論?我指向要求的文件,並建議使用提到的自旋鎖的替代方案。 – IvoTops 2012-07-06 13:24:05