2012-04-20 511 views
3

我使用的並行線程在C.如何resuse線程 - 並行線程ç

我有需要創建4個線程ID爲0,1,2父線程,3 當父線程得到編程數據,它將設置拆分數據並將其分配給4個獨立的上下文變量 - 每個子線程一個。 子線程必須處理這些數據,同時父線程應該在這些線程上等待。 一旦這些子線程完成執行,它們將在相應的上下文變量中設置輸出並等待(重用)。 一旦父線程知道所有這些子線程都完成了這一輪,它就會計算全局輸出並將其打印出來。 現在它等待新的數據(子線程還沒有被殺死,他們只是在等待)。

如果父線程獲取更多數據,則重複上述過程 - 雖然已經創建了4個線程。

如果父線程收到一個kill命令(假設有特定類型的數據),它會向所有子線程指示並且它們自行終止。現在父線程可以終止。

我是碩士研究生,我遇到了上述情況的需要。我知道這可以使用pthread_cond_wait,pthread_Cond_signal來完成。我寫了代碼,但它只是無限期地運行,我不知道爲什麼。

我的猜測是,我編寫它的方式,我已經過度複雜的情況。瞭解如何實施這將是非常有幫助的。如果有需要,我可以發佈我的代碼的簡化版本,以顯示我正在嘗試做什麼(儘管我認爲我的方法有缺陷!)...

您能否給我提供任何見解如何使用pthreads來實現這個場景?

+0

你可能想看看[這篇文章](http://stackoverflow.com/q/9275262/777186),其中的答案描述了各種主/工場景。還有一個答案詳細描述瞭如何使用POSIX。 – jogojapan 2012-04-20 05:04:04

+0

對於所有四個線程完成其工作後所需的同步,您可能需要查看一下:http://www.lambdacs.com/cpt/FAQ.html#Q292 – alk 2012-04-20 06:45:14

回答

1

至於從您的描述中可以看出,原則似乎沒有錯。

你試圖實現的是一個工作池,我想應該有很多的實現。如果你的線程正在做的工作是一個大量的計算(比如說至少有一個CPU時間),這樣的方案是一個完整的矯枉過正。 Mondern實現的POSIX線程足夠高效,它們支持創建大量的線程,真的很多,而且開銷並不高。

如果讓工作人員通過共享變量,互斥鎖等(而不是通過線程的返回值)進行通信,唯一重要的是您可以使用屬性參數pthread_create來啓動線程分離。

一旦你有你的任務這樣的實施,測量。只有這樣,如果您的分析器告訴您在pthread例程中花費了大量時間,請開始考慮實施(或使用)工作池來回收您的線程。

+0

當我使用此池概念時,我的程序將創建160000個線程。如果我不使用線程池,那麼這個數字將增加到160萬 - 這是一個10倍的增長。它會不會影響時代? – 2012-04-20 17:37:23

+0

@TheFlyingDutchman,我該怎麼知道。你沒有給我們任何暗示你的線程真正做什麼,他們花了多少時間來完成應用任務以及多少開銷。測量,你會知道。 (請分享。) – 2012-04-20 18:33:41

+0

@TheFlyingDutchman - 如果您在池中只創建16個工作線程,並且再也不做任何工作,那麼將只有16個工作線程。 – 2012-04-20 21:28:12

0

一個生產者 - 消費者線程掛了4個線程。希望對四個任務進行排隊的線程將包含四個上下文結構以及所有其他數據內容的函數指針組裝到一個「OnComplete」函數中。然後它將所有四個上下文提交到隊列中,原子上將taskCount遞增到4,並等待事件/ condvar /信號量。

四個線程從P-C隊列中獲取上下文並消失。

完成後,線程調用'OnComplete'函數指針。

在OnComplete中,線程自動向下計數taskCount。如果線程將其遞減爲零,則表示事件/ condvar /信號量和原始線程運行,知道所有任務已完成。

安排它並不困難,以便上下文和同步等待的彙編也在任務中完成,因此允許池一次處理多個請求線程的多個「ForkAndWait」操作。

我必須補充說,像這樣的操作在OO語言中更容易。例如,最新的Java有一個'ForkAndWait'線程池類,它應該完全做這種東西,但是C++(或者甚至C#,如果你進入農奴制的話)比C更好。