2011-04-20 46 views
0
for (int i = 0; i < 100; i++) 
{ 
     // If current thread needs resource(i) then 

     Mutex mutex = new Mutex(false, "Mutex" + i.ToString()); 
     mutex.WaitOne(); 

     // synchronized access to resource(i) 

     mutex.ReleaseMutex(); 
} 

我們有100個資源,每個人都應該由單個線程併發訪問同步訪問命名mutexs(這是確定訪問資源[2]和資源[5]同時),所以我使用了上面的代碼。在這種情況下,命名互斥體的最佳選擇是什麼?最佳替代對每個資源

回答

2

如果這全部在一個進程中,那麼根本就不需要命名互斥鎖。只需創建一個N對象列表或數組並使用lock

const int NumLocks = 100; 
List<object> LockObjects = new List<object>(NumLocks); 

// to initialize 
for (int i = 0; i < NumLocks; ++i) 
{ 
    LockObjects.Add(new object()); 
} 

// and your loop 
for (int i = 0; i < NumLocks; ++i) 
{ 
    // if current thread needs lock[i] then 
    lock(LockObjects[i]) 
    { 
     // do whatever you need to do 
     // and then release the lock 
    } 
} 

或者,您可以鎖定單個資源對象。如果他們真的是物體。我發現使用單獨的鎖對象更容易理解和維護,因爲「資源」可能是一個方法或一組對象。鎖對象是一個抽象,對我來說,它有助於理解。

如果多個進程需要這個,那麼除了使用Mutex之外,我沒有看到一個好的解決方案。但是,我建議在程序開始時創建這些對象的列表,並保持它們周圍。這樣,在循環中,你所要做的就是WaitOne - 每次循環中都不需要創建對象。

+0

實際上資源沒有索引。他們有獨特的名字,所以有'resource [key]'而不是'resource(i)',那麼什麼類型適合用作鎖? – Xaqron 2011-04-20 23:42:29

+0

我會建議使用我發佈的解決方案,並使用'List '作爲鎖。所以爲了使用'resource [key]',你鎖定了'LockObjects [key]'。如果'key'不是一個連續的整數,那麼爲這個鎖建立一個'Dictionary '。只要鎖對象和資源之間存在一對一的關係,你應該沒問題。 – 2011-04-21 07:04:20

1

假設資源是引用類的實例,只需鎖定每個資源即可。

var r = resource(i); 
lock (r) 
{ 
    // synchronized access to resource(i) 
} 
+0

不幸的是資源是'懶惰'的對象,我不喜歡不必要地喚醒它們,但這個想法很有創意。 – Xaqron 2011-04-20 23:22:25