2014-10-02 40 views
0

我們有一個非常接近生產者 - 消費者問題的問題集。實際使用情況是針對通過目錄列表(生產者)運行的線程(大約2000條),然後將這些條目提供給處理這些目錄中特定文件的4個線程(消費者)。在生產者繼續之前等待所有異步消費者完成

我們試圖解決的問題是如何讓生產者線程在繼續之前等待最終消費者完成。一旦我們將所有文件存儲在內存中,只有在讀取完所有文件後才能完成後期處理。

我們已經實現了一個基於忙等待很天真計數器的解決方案,投票類計數器(計數器由生產增加,由消費者遞減,由一個互斥保護):

while(fileCnt > 0) { 
    usleep(10000); 
    } 

這是事業的不一個很好的解決方案。

有沒有通過條件/信號量/其他方法做到這一點?

我們僅限於非C++ 11實現(基於pthread)。

謝謝。

+0

這些消費者正在通過cv + mtx受保護,誰的內容大小是其中的一部分謂詞檢查,是嗎? – WhozCraig 2014-10-02 08:10:27

+1

典型的方法是有一個信號量,並預先加載隊列大小的信號量(例如4,5或8,以允許生產者爲消費者準備一些項目)。然後在信號量的上下用來指示剩餘的空間量,當信號量爲零時,它等待對方消耗下一個項目) – 2014-10-02 08:11:14

+0

@WhozCraig「我們僅限於非C++ 11實現(基於pthread)「。 ---除非你提出推薦變體。 – Jagannath 2014-10-02 08:17:15

回答

1

嗯..這對於一般情況來說實際上很難做到高效。如果您在提交第一個條目之前知道要提交隊列中的多少個對象(如您所看到的那樣),則更容易:

將原子整數設置爲要提交的對象數。在每個處理完每個對象的線程調用的每個項目中加載一個回調。該回調將int遞減爲零。當一個線程將其解析爲零時,它發出一個同步對象的信號,生產者在排隊其最後一個對象後正在等待一個同步對象。

我還在想着這裏到底是排隊的第一項:(

的話,可能需要回調的實際鎖定之前做什麼,如果生產者是迭代一些名單,不知道這麼生產者可以輸入它並檢查所有排隊的操作是否完成,如果沒有,則退出鎖定後等待同步對象,如果同步對象保持狀態,例如信號量,則更安全,以便在退出鎖定之後,但在等待之前產生的信號不會被遺漏,(不知道如何使用condvar安全地執行它)。

+0

我們使用2個互斥對象來實現上述功能,它的工作原理相當好。謝謝。 – user626201 2014-10-06 08:18:58

相關問題