c#lock關鍵字是否使用'yielding','spin-locking'或混合方法來處理爭用?鎖語句使用什麼類型的鎖定機制
到目前爲止,我在.net鎖定語句中的搜索沒有找到答案。 我會發布,如果我找到任何更多。 到目前爲止,我所能找到的是When should one use a spinlock ...,其中有一個措辭很好的Mecki接受的答案。
但是我正在尋找一些關於.net/c#的明確答案或文檔,如果任何人有一個。
c#lock關鍵字是否使用'yielding','spin-locking'或混合方法來處理爭用?鎖語句使用什麼類型的鎖定機制
到目前爲止,我在.net鎖定語句中的搜索沒有找到答案。 我會發布,如果我找到任何更多。 到目前爲止,我所能找到的是When should one use a spinlock ...,其中有一個措辭很好的Mecki接受的答案。
但是我正在尋找一些關於.net/c#的明確答案或文檔,如果任何人有一個。
以下代碼:
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編譯器,算法對於不同的硬件可能會有所不同)。
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);
}
這是微軟的文檔說鎖()包裝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
爲什麼downvote這個沒有評論?我指向要求的文件,並建議使用提到的自旋鎖的替代方案。 – IvoTops 2012-07-06 13:24:05
沒有在最近的編譯器版本,它不是 – 2012-07-06 12:35:42
@MarcGravell所以我只注意到。剛剛花了最後10分鐘閱讀FAIC :) – DaveShaw 2012-07-06 12:39:25