2012-06-16 42 views
1

我有一個單鏈表,每個元素中包含1個值。與pthreads彈出列表的大小填充列表

struct listElement 
{ 
    char guid[20]; 
    struct listElement *next; 
    struct listElement *last; 
    int numElements; 
}; 

代碼啓動的池都pthread_cond_wait()一個元素得到添加到列表10個並行線程。

我的main()函數讀取從文件中的字符串,每次一個行,並通過調用listPush(val)

listPush(val)獲得鎖,創造了新的元素填充鏈接列表,添加到結束列表(或創建頭,如果空)解鎖,然後調用pthread_cond_signal()讓10個線程中的一個知道現在有一個元素需要完成。

在numElements> numThreads我調用pthread_cond_broadcast()的情況下,因爲每個線程都應該有足夠的工作來彈出和去除。

每個線程listPop(rVal)關閉一個值(鎖定,刪除,修復指針,解鎖)並對其進行處理,然後返回到pthread_cond_wait()狀態。

我的文件大約有2億行。 (1.2GB)我不想讓我的鏈表得到這個大,所以我試圖「扼殺」鏈表的大小。

裏面listPush(),我才鎖定互斥體,我有

if(head && head->numElements >= maxNumElements) 
{ 
    while(head && head->numElements >= maxNumElements) 
    { 
     sleep(1); 
    } 
} 

的想法是,如果我「填補」我的名單,我等待的線程來增加更多的之前處理它的一大塊。我已經達到了應用程序開始「脈動」的這一點。基本上我可以看到它等待1秒。我希望這種情況永遠不會發生或很少發生。

除了使用sleep()以外,是否有更好的方法來限制我的列表大小?

+0

*解鎖然後調用pthread_cond_signal()* - 信號通常在臨界區內完成,即在解鎖之前完成。 – chrisaycock

+0

每個消費者線程還應該告知下一個消費者,如果列表在pop之後仍然是非空的。 – jxh

+0

@chrisaycock:這可能是如何經常完成的,但沒有要求。實際上,它可能會在一定程度上減少互斥體的爭用。 –

回答

0

這聽起來像一個經典的producer-consumer problem。如果列表太大,解決方法是讓listPush()等待條件變量。然後,一旦消耗了列表元素,其中一個消費者線程可以發信號通知這個條件變量。

完全不同的方法是隻使用一個pipe()同時處理通信和同步。這將消除對鏈表和互斥量的需求。

+0

閱讀手冊頁後,'p​​ipe()'看起來就是我正在尋找的東西。從來不知道。謝謝。我會試一試。 – utdrmac

0

是的,而不是使用睡眠,你可以等待一個信號量(類似於一個互斥體,但在其他方式),當新的元素添加到列表中被喚醒。您可能能夠找到事件庫或使用pthread自行完成。