2011-08-18 66 views
2

我正在使用QProcess對象列表來跟蹤某些需要按用戶定義的間隔啓動/停止的進程。QProcess變得不可用並且無法再次啓動

我可以啓動和停止進程確定。但問題出現時,我使用以下方法(僞代碼)停止一個進程:

process->start("PathToProcess","Some Arguments"); 
//Do some stuff. 
process->terminate(); 

但是,如果我嘗試在其他時間重新開始的過程中,我得到的錯誤:

QProcess::start: Process is already running 

我可以做一個ps -ef | grep processName,並發現它確實已經死了,但它正處於一個已經停止的狀態,我認爲這阻止了我再次啓動它。

我需要做些什麼來防止這種不存在的狀態,或者刪除已停用的方法,以便我可以在不重建的情況下再次啓動我的過程?

+0

你是否檢查過'process-> processState!= NotRunning'?有時候孩子會在沒有適當退出的情況下死亡。 – mbx

+0

終止後,爲了進行更多測試,我添加了一個終止後,儘管在操作系統中處於停止狀態,但該過程仍顯示爲「正在運行」。好決定。好像我可能需要自己做setProcessState。 –

回答

7

找出導致錯誤的原因。

在qprocess_unix.cpp中,您會發現一個名爲QProcessManager的類。本質上講,這個類具有監視已經死亡的子進程的信號處理程序。當一個孩子死亡時,QProcessManager通過一個管道發送一條消息,讓QProcess類知道它終止/死亡。

在我的代碼的不相關部分中,我設置了一些信號捕捉語句,用於各種用途。但是,這些信號捕獲正在捕獲我的SIGCHLD事件,因此QProcessManager從未被觸發以管道傳輸到它死亡的QProcess。

在我的情況下,我唯一的選擇是要麼手動觀察孩子的死亡,要麼刪除我在其他代碼段執行的信號捕獲。

爲了將來的參考,如果你有這個問題,你最好做POSIX調用殺死和終止,並手動檢查這些調用的返回值。如果成功,執行:

process->setProcessState(ProcessState::NotRunning);//Specify the process is no longer running 
waitpid(process->pid(),NULL,WNOHANG); //Clear the defunct process. 

謝謝大家。

+0

也發生在我身上,使用貓鼬時(最後一個免費版本):引起了一些頭部劃傷;) – mBardos

2

撥打process->terminate()致電process->waitForFinished()以獲得殭屍進程。然後您可以重新使用該過程對象。

+0

不好看。當進程結束時,它不會發出完成的()信號,所以waitForFinished()永遠不會觸發。我認爲當一個程序結束時,它會將狀態從運行狀態改變爲不運行狀態,但看起來並不是這種情況。我會繼續看着它。 –

+0

當我用'process-> start(「sleep 60」)測試時;流程 - >終止(); process-> waitForFinished();'它爲我工作。 –

+0

出於某種原因,我的「process-> terminate()」從不發送完成的()信號。所以waitForFinished()對我來說是失敗的。 –

相關問題