2012-06-29 35 views
2

我想創建一個線程池。我有一個名爲ServerThread.cpp類,它的構造應該做這樣的事情:可以在構造函數內創建Pthreads嗎?

ServerThread::ServerThread() 
    { 
     for(int i=0 ; i<init_thr_num ; i++) 
     { 
       //create a pool of threads 
       //suspend them, they will wake up when requests arrive for them to process 
     } 
    } 

我在想,如果在構造函數中創建並行線程可能會導致任何不確定的行爲人應該避免陷入。

感謝

回答

5

你當然可以這樣做,在一個構造函數,但應該知道,這顯然是斯科特邁爾斯解釋的問題INS他的有效/更有效的C++書籍。

總之他的觀點是如果在構造函數中引發任何類型的異常,那麼你的半支持對象將不會被銷燬。這導致內存泄漏。所以邁爾斯的建議是讓「輕」的構造函數,然後在對象完全創建後調用的init方法中執行「重」工作。

此參數與在構造函數中創建pthread池無關(因此您可能會爭辯說,如果您只是簡單創建它們並立即掛起它們,則不會引發異常),但是對於什麼在構造函數中做(閱讀:最佳實踐)。

要做的另一項考慮是構造函數沒有返回值。儘管確實(如果沒有拋出異常),即使線程創建失敗,也可以使對象保持一致的狀態,但最好從一種initstart方法管理返回值。

您還可以閱讀關於該主題的this thread on S.O.,以及this one

+1

這已無關,與線程,斯科特的建議已經在很大程度上被更先進的技術所取代:例如擁有由基類或成員管理的資源,這些資源將在進入構造函數體之前完全構建。 (在這種情況下,線程池應該是一個成員,所以如果發生異常,它的析構函數將被調用。) –

+0

@James Kanze:在我的回答中,我已經指出了以下內容:「這個論點並不嚴格與在構造函數中創建pthread池有關「,而是」良好實踐「。此外,您在評論和自己的回答中都確認,建議使用某些特定技術來正確處理此問題。一個'init'方法儘管年代久遠或簡單,但只是其中一種技術。無論如何,感謝您的評論。 – sergio

2

從嚴格的形式上來看,一個構造函數實際上只是一個 函數,不存在任何問題。 實際上,可能存在一個問題:線程可能實際上在構造函數完成之前開始運行 。如果線程需要一個 完全構造ServerThread操作,那麼你就麻煩 這—通常情況下,當ServerThread是一個基類 和線程需要與派生類交互。 (這 是很難發現的問題,因爲最頻繁 使用的線程調度算法,新的線程將通常不 開始立即執行。)

相關問題