2010-09-17 75 views
0

我正在編寫一個系統,用於自動重新計算代價高昂的方法的結果,然後將它們存儲在緩存中。緩存可能是分佈式的,這意味着(顯然)多個進程可以訪問它。進程間鎖

在第一次調用方法來緩存結果時,我想產生一個線程,它會定期重新計算方法的結果並更新緩存。

我只想爲每個緩存項目生成一個單一的執行線程。在多進程環境中,這可以通過使用像這樣的跨進程互斥來實現嗎?

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

是否有使用這種方法的任何陷阱?

編輯:我實現

真值表:

// in-cache | mutex-found 
// 0   0  //not in cache, no mutex; start thread 
// 1   0  //in cache, no mutex; assume thread already started (re-calculating thread could be in another process) 
// 0   1  //not in cache, mutex found; thread started, do not start thread - log error (and possibly start new thread) 
// 1   1  //in cache, mutex found; thread started, do not start thread 

回答

2

總之,我認爲這是一個不錯的辦法。唯一的缺陷是互斥體識別 - 如果可能的話,通過其句柄告訴次要線程關於互斥體。如果必須使用已命名的互斥鎖,則可能需要將互斥鎖的名稱與流程UUID相同以提升唯一性。

0

再次想到,可能有更簡單的方法來做到這一點。鑑於你對緩存的描述是「週期性重新計算」的,而不是線程,你可以擁有一箇中央的System.Threading.Timer。由於它只能與單個回調關聯,因此不存在多個線程嘗試重寫高速緩存的風險。唯一需要注意的是,這個計時器事件需要以原子方式對高速緩衝存儲器進行單次寫入(不會在寫入過程中被另一個線程中斷)。

+0

雖然這樣的計時器是可見的進程間? – Ben 2010-09-18 03:27:08

+0

我認爲它不需要:你所擁有的只是一個進程間布爾標誌,表示定時器已被某人實例化。結合前面的解決方案,您的進程間對象可以是「已分配計時器」標記,並且僅在緩存正在被重寫時使用的互斥量以及緩存本身;定時器可以是線程本地的。 – Reinderien 2010-09-18 04:23:47

+0

使用緩存對象的存在性作爲計時器已分配標誌,而不是單純依賴互斥體是否具有性能優勢?我試圖理解你的方法。 – Ben 2010-09-18 09:09:47