2013-03-21 61 views
3

在我們的應用程序中,我們處理在工作線程中處理並在顯示線程中訪問的數據,並且我們有一個互斥體負責處理關鍵部分。沒什麼特別的。保護數據設計模式

現在我們考慮重新處理我們的代碼,當前鎖定由持有和處理數據的方明確地完成。我們想到了一個擁有數據的實體,只能以保護的方式訪問數據。

爲此,我們有一個名爲GuardedData的類。調用者可以請求這樣一個對象,並且應該在本地範圍內只保留一小段時間。只要對象存在,它就會保持鎖定狀態。一旦對象被銷燬,鎖就會被釋放。數據訪問與鎖定機制相結合,無需在調用者中進行任何明確的額外工作。班級的名字提醒現在的警衛的來電者。

template<typename T, typename Lockable> 
class GuardedData { 
    GuardedData(T &d, Lockable &m) : data(d), guard(m) {} 
    boost::lock_guard<Lockable> guard; 
    T &data; 

    T &operator->() { return data; } 
}; 

再次,一個非常簡單的概念。運算符 - >模仿STL迭代器的語義以訪問有效負載。

現在我不知道:

  • 是這種方法衆所周知的?
  • 是否有像這樣的模板類已經可用,例如:在boost庫中?

我在問,因爲我認爲這是一個相當通用和可用的概念。雖然我找不到像這樣的東西。

+1

我有數據可以在後臺訪問時在前臺進行更改。有效地,當背景計算完成時,數據被交換。當有人訪問數據時,這種交換不應該發生,這可能導致該方進入不一致的狀態。我們需要做交換而不是創建一個新的實例,而其他人仍然使用舊的實例。原因是同時駐留在內存中的大量數據。 – ypnos 2013-03-21 13:59:12

回答

1

衆所周知,我不確定。但是,我在Qt中使用了類似的機制,通常稱爲QMutexLocker。這個區別(小的一個,imho)是你將數據和互斥鎖綁定在一起。與您所描述的機制非常類似的機制是C#中線程同步的標準。

您的方法很適合一次監視一個數據項,但如果您需要保護更多,則會變得很麻煩。此外,它看起來並不像你的設計會阻止我在共享位置創建這個對象,並且經常訪問數據,認爲它被完全保護好了,但實際上遞歸訪問的場景不會被處理,也不會被處理多線程訪問方案(如果它們出現在相同範圍內)。

這個想法似乎有一點點的脫節。它的使用傳達給我的是,訪問數據始終是線程安全的,因爲數據是被保護的。通常,這不足以確保線程安全。受保護數據的操作順序通常很重要,因此鎖定實際上是面向範圍的,而不是數據導向的。你可以通過守護一個虛擬對象並將你的守護對象包裝在一個臨時範圍中來解決這個問題,但爲什麼不僅僅使用一個現有的互斥體實現呢?

真的,這不是一個壞的方法,但你需要確保它的預期用途被理解。

+0

我認爲QMutexLocker與boost :: lock_guard本身相同。它們都是互斥量/版本的RAII/RRID封裝。 – Pete 2013-03-21 15:25:46

2

根據使用方法的不同,幾乎可以保證在某個時刻結束死鎖。如果你想操作2段數據,那麼你最終會鎖定互斥鎖兩次併發生死鎖(除非每段數據都有自己的互斥鎖 - 如果鎖定順序不一致,這也會導致死鎖 - 你無法控制用這個方案不會讓它變得非常複雜)。除非你使用可能不需要的遞歸互斥體。

另外,你的GuardedData對象是如何傳遞的?boost :: lock_guard不可複製 - 它會引發互斥體的所有權問題,即發佈時的所有權問題&。

它可能更容易將您需要的部分數據複製到讀寫器線程,並在需要時將其保留在關鍵部分中。作者將同樣致力於數據模型。

本質上,您的查看器線程可以在給定的時間獲取所需數據的快照。這甚至可能完全適合位於正在運行線程的核心附近的cpu高速緩存,並且永遠不會將其放入RAM中。編寫器線程可能在讀者正在處理它時修改底層數據(但應該使視圖無效)。但是,由於觀衆有一個副本,它可以繼續,並在與數據同步時提供數據視圖。

另一種選擇是給視圖一個智能的數據指針(它應該被視爲不可變的)。如果作者希望修改數據,則在此時複製數據,修改副本並在完成時將指針切換到模型中的數據。這將需要在處理時阻止所有讀者/作者,除非只有一個作者。讀卡器下一次請求數據時,會得到新的副本。

+0

所以第二次迭代是使用boost :: recursive_mutex而不是lock_guard。 – ypnos 2013-03-21 14:24:06

+0

有問題的數據對象可能達到幾千兆字節,因此避免冗餘副本很重要。 – ypnos 2013-03-21 14:25:15

+0

您是否需要每次都複製所有數據?允許外部客戶管理鎖定很可能最終會出現問題。 – Pete 2013-03-21 15:05:29