2014-01-10 34 views
4

我一直在想如何lock(或更具體的:Monitor)在.NET內部工作,關於被鎖定的對象。具體來說,我想知道什麼是開銷,是否使用了'全局'(進程)鎖,如果可以創建更多的全局鎖(如果是這種情況)(對於監視器組),以及對象傳遞給鎖(它們似乎不會引入額外的內存開銷)。`lock`(Monitor)如何在.NET中工作?

爲了澄清我沒有問的問題:我在這裏不是問什麼是Monitor(我前一年在大學做過)。我也沒有問如何使用lock,Monitor,它們是如何編譯爲try/finally等的;我很清楚這一點(還有其他與此相關的SO問題)。這大約是內部工作Monitor.EnterMonitor.Exit

例如,考慮十個線程執行該代碼:

for (int i=0; i<1000; ++i) 
{ 
    lock (myArray[i]) 
    { 
     // ... 
    } 
} 
  • 它是壞的鎖千個對象而不是一個?對性能/內存壓力有什麼影響?
  • 底層監視器創建一個等待隊列。是否有可能有多個等待隊列,我將如何創建?
+0

不知道我知道你問什麼。用作「鎖」的對象只是對引用類型的引用。對象內部無關緊要。 'Monitor.Enter'將會看到有關的引用是否在其已經保存的「鎖」的集合上。如果是,它會阻塞線程,直到參考爲空。如果鎖定/變爲空閒,它將被採用(放入該引用集合中),並保存到'Monitor.Exit'中。在你的例子中,如果'myArray'的類型爲'X []'',其中'X'是一個引用類型(即不是結構或枚舉類型),那就沒問題。取決於塊內部的內容。 –

+1

請參閱http://stackoverflow.com/a/1808722/517852 –

+0

另外http://joeduffyblog.com/2007/06/24/clr-monitors-and-sync-blocks/和http://msdn.microsoft。 com/en-us/magazine/cc188793.aspx –

回答

5

Monitor.Enter不是一種常規的.NET方法(不能用ILSpy或類似方法進行反編譯)。該方法由CLR在內部實現,所以嚴格來說,.NET不存在任何答案,因爲不同的運行時可以有不同的實現。

.NET中的所有對象都有一個對象頭,其中包含一個指向對象類型的指針,而且還有一個SyncBlock索引到SyncTableEntry。通常情況下,索引是零/未使用,但是當你鎖定對象時,它將包含一個索引到SyncTableEntry,該索引包含對實際鎖定對象的引用。

因此,成千上萬的對象的鎖定確實會產生很多鎖,這是一種開銷。

我找到的信息是MSDN文章中:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx

+0

對,它回答了我正在尋找的大部分內容。我提到的全局鎖是'SyncTableEntry'周圍的自旋鎖,內存開銷大約爲72個字節。性能開銷取決於散列 - 假設碰撞次數非常少,這可能大致爲0.問題仍然存在:是否可以創建多個可同步的 - 儘管我認爲這是不可能的。 – atlaste

1

Here是一個很好的地方,瞭解顯示器,記憶障礙等

編輯從頁面

屏幕截圖案頁面將來成爲下: enter image description here

+1

您應該從網站添加一些信息,以防止該頁面將來變得不可用。 –

+0

好點,thx。其實我已經看到了這個頁面,因爲我記得:D – SOReader