2010-10-01 73 views
3

我知道有類似的問題已經得到解答,但我提出這個問題,因爲他們並不完全給我想知道的。 這是關於線程之間的同步。我的項目的想法是我們從數據採集卡獲取數據並在數據採集過程中繪製和分析數據。到目前爲止,我只有一個線程上的數據採集類和另一個線程上的繪圖類。數據採集​​類將數據存儲在全局循環緩衝區中,並且繪圖類從全局緩衝區複製數據,並執行一些繪圖過程(減少數據點等)。這就是我認爲所謂的(單一)生產者 - (單一)消費者問題。我設法使用兩個信號量來完成這一部分,這兩個信號跟蹤採集類存儲了多少個數據點以及繪圖類使用了多少個數據點。在線程之間共享數據數組-C++

現在,我想介紹另一個線程分析數據的另一個類。那麼,我會有一個生產者和兩個消費者。我想強加以下條件:

  1. 這兩個閱讀器共享相同的數據集。即,每個生產的產品 必須由兩個讀取器 使用,而不是僅由其中的一個讀取器使用。
  2. 緩衝區滿時,數據採集類將覆蓋全局緩衝區 。當 讀取器(或多個)失去數據由於 重寫由 數據採集類的緩衝液中,這必須 被檢測,並且理想地,保持在 日誌(例如,什麼 數據的一部分被遺漏由readear(s))。
  3. 分析 類的計算可能是密集型的。爲此, 我可能需要更大的數據緩衝區 分析類。

我處理第一部分(單一生產者和單一消費者)的方式似乎沒有以直接的方式擴展到第二部分(單一生產者和兩個消費者)的情況。我想知道我應該如何繼續。 我使用C++與Qt進行線程化,因爲我使用Qt GUI。但是,解決方案並不一定要用Qt。但是,如果可能的話,將不勝感激示例代碼或僞代碼。我發現了一個類似的線程,我的問題here)。建議使用boost :: interprocess。然而,由於我以前從未使用過Boost庫,雖然我已經閱讀過關於boost :: interprocess的文檔,但它看起來過於牽扯到弄清楚我自己。

非常感謝!

大輔

回答

2

如果同時消費者需要看到所有數據項,你可能每消費一個緩衝區更好。生產者然後可以將相同的數據發佈到每個緩衝區中。如果您擔心以這種方式加倍數據的內存要求,並且數據不會被用戶修改,則可以使用引用計數指針(如boost::shared_ptr),並將指針指向數據到每個緩衝區。這樣數據項是共享的,但讀者可以獨立處理數據。

讓生產者日誌覆蓋一些數據應該是非常微不足道的。

+0

感謝您的回覆。到目前爲止,記憶並不是一個大問題。所以,我將從每個消費者的緩衝開始。對於每個消費者的緩衝區,你會建議使用什麼?我可以想到的一件事是STL中的一個隊列,隊列:: push()來自生產者的數據和隊列::消費者使用後的數據。這是個好主意嗎?有一件事是我的製作人一次創建大量數據(大約10,000個雙精度或整數元素)。如果我排隊:: push()每個元素,它會有點慢嗎?謝謝! – Daisuke 2010-10-02 09:51:59

+0

如果您的製作者一次創建了一大塊元素,請將它們作爲一個塊推入。由於這是一個單消費者隊列,消費者可以確保它按照正確的順序處理塊中的元素。 – 2010-10-02 22:43:57

+0

STL中的隊列是否允許我將元素推送爲塊?或者我應該繼承這個類並創建一個成員函數來這樣做?如果後者是這種情況,你會如何做到這一點? – Daisuke 2010-10-03 18:41:57

0

我想你應該閱讀香草薩特以下併發文章,瞭解你應該如何構建的東西,以及如何可擴展性(如果這是一個目標)的感覺。下面的鏈接是最新的文章,但也包含以前的完整列表。

http://herbsutter.com/2010/09/24/effective-concurrency-know-when-to-use-an-active-object-instead-of-a-mutex/

概括地說,如果可能的話,你應該使數據的副本爲每個線程以減少對實際資源而不是互斥體包裹的一切爭。這個arcticle是關於這個的。

http://herbsutter.com/2008/05/23/effective-concurrency-maximize-locality-minimize-contention/

+0

感謝您的建議。複製數據是一個好主意。我正在考慮在互斥體中包裝所有東西。也感謝文章鏈接。這些文章看起來有點濃重。但是,我會花一些時間閱讀它們。希望我可以通過併發編程來提高成熟度。 – Daisuke 2010-10-02 09:55:51