2011-08-18 67 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()对我来说是失败的。 –

相关问题