2012-12-19 50 views
1

我有6個線程在我的應用程序中不斷運行。場景是:在C++中處理boost線程爭用條件

一個線程不斷獲取消息並插入到消息隊列中。其他4個線程可以被認爲是連續從隊列中獲取消息並處理它們的工作者。另一個最終線程填充分析信息。

問題:

現在獲得消息線程的睡眠持續時間是100ms。工作者線程是200ms。當我運行這個應用程序時,消息獲取線程正在控制並插入隊列,從而增加了堆。工作線程沒有機會處理消息並釋放它們。最終導致內存不足。

如何管理這種場景,以便爲消息獲取線程和工作者線程提供平等的機會。

感謝提前:)

+1

這被稱爲[讀者 - 作家問題](http://en.wikipedia.org/wiki/Readers-writers_problem)。也許這個關鍵字可以幫助你進行搜索。通常你的作者(提取)會檢查當前是否有讀者在等待和暫停。另一方面,你的讀者(工作人員)會檢查是否有作者在等待。如果使用條件變量,實現基本功能非常簡單。 – Zeta

回答

1

你的問題有點模糊,所以我可以給你這些指導方針,而不是代碼:

  1. 維護雙方的數據與互斥。在多線程consumer producer問題中,通常互相數據(程序中的消息)存在爭用條件。一個線程試圖在相互的內存位置進行寫操作,而另一個線程則試圖從相同的位置讀取。讀者閱讀的信息可能會被破壞,因爲作者在閱讀過程中寫過信息。您可以使用Mutex鎖定相互的內存位置。每個線程都應該獲得這個鎖,以便能夠讀取或修改相互的數據。這樣消費者過程將會絕對確保數據沒有被修改。但是您應該注意獲取此鎖可能會阻止生產者線程,因此您應儘快釋放鎖。
  2. 使用條件變量來通知消費者線程。如果您不使用通知機制,則所有消費者線程都應主動檢查將耗盡系統資源的數據生產。消費者線程應該很容易進入睡眠狀態,因爲知道生產者線程會在消息準備就緒時通知他們。

C++ 11中的線程庫擁有實現用戶生產者應用程序所需的所有功能。但是,如果你不能升級你的編譯器,你也可以使用boost線程庫。

1

您要使用受限制隊列這充分時會阻塞線程試圖排隊,直到有更多的可用空間。

您可以使用concurrent_bounded_queue from tbb,或者簡單地使用初始化爲最大隊列大小的信號量,並在入隊和出隊時遞減。 boost :: thread本身不提供信號量,但是你可以使用鎖和條件變量來實現它。

+0

+1用於提示TBB隊列。 –

4

您需要向生產者線程添加背壓。通常這將通過使用阻塞的消費者 - 生產者隊列來完成。生產者將項目添加到隊列中,消費者從隊列中取出隊列並處理它們。如果隊列爲空,消費者會阻塞,直到生產者添加一些東西到隊列。如果隊列已滿,則生產者阻止,直到消費者從隊列中獲取項目。

4

我經常使用的一個流量控制系統是在啓動時創建大量消息對象並且不再創建。 *對象存儲在一個線程安全的阻塞的「池隊列」中,並循環播放,由生產者/池從池中彈出,排隊到其他阻塞隊列中的消費者,然後在「消耗」時推回到池隊列中。 (如果池清空,直到從消費者返回消息爲止的生產者/塊),並且消除連續的新/刪除/ malloc/free,則會限制內存的使用,提供流量控制(012)。更復雜和更慢的有界隊列不是必需的,並且所有隊列只需足夠大以容納(已知)最大數量的消息。

使用'傳統'阻塞隊列不需要任何Sleep()調用。