2012-06-03 36 views
2

我有一個C++ pthread線程使用Popen調用shell腳本。pthread_join失敗會導致子進程成爲殭屍嗎?

在一種情況下觀察到的情況是捕獲到pthread_join失敗(即pthread_join!= 0)並且子進程保持爲殭屍(按ps輸出)。

這也會導致主程序掛起。

現在,我不知道爲什麼pthread_join會失敗,因爲它在其他情況下從未做過。

但我想知道是否收集Popen產生的子進程的等待狀態是thread_join的一部分。如果是這樣至少我可以肯定的是,連接失敗的根本原因殭屍和程序掛起..

在此先感謝..

+0

是的,我有這個想法。還沒有嘗試,因爲pthread_join被封​​裝爲一個公共庫。我已經放棄了下一次測試.. – Vivek

回答

1

調用popen後,需要有對pclose相應通話,否則由popen調用產生的子進程將保持殭屍狀態。可能發生的情況是該線程遇到未處理的異常,導致pclose不被調用,導致殭屍和pthread_join的「失敗」結果。

一個解決方案是確保您的代碼正確處理所有可能的異常。

另一種解決方案是實現類似popen()的東西,但不需要pclose()收穫殭屍。這可以通過使用雙叉來完成。您致電fork(),然後再打電話給exec()。父進程允許中間子進程退出並通過wait4()獲得。孫子過程現在可以不離開殭屍而離開,因爲它將被init過程收割。要創建孫子和父母之間的溝通渠道,請使用pipe()作爲popen(),如果您需要雙向溝通,請使用socketpair()。在孫子過程中使用dup2(),以便在致電exec()之前允許您選擇stdin,stdoutstderr通過管道或插座重定向。

+0

這似乎是有道理的。因爲只有在底層套接字引發異常時纔會發生此連接失敗。但try-catch捕獲加入失敗..我會檢查它是否是pclose情況並更新條件。 – Vivek

+0

我有一個疑問。如果我的主進程有一個SIGCHLD的信號處理程序並實現等待,那麼即使連接失敗殭屍也不會移除嗎? – Vivek

+0

我接受你的答案,因爲這幫助我解決了這個問題。前一個線程在加入後處理異常時留在列表中,噹噹前線程結束時,該列表再次遍歷以便加入。再次加入會導致失敗,因此此線程永遠不會加入,從而導致殭屍進程和進程掛起。謝謝:) – Vivek