【问题标题】:Kill QProcess that was stopped and resumed杀死已停止并恢复的 QProcess
【发布时间】:2019-01-14 13:20:52
【问题描述】:

我有一个必须暂停和恢复的 QProcess。我用

kill(pid_t(process->pid()), SIGSTOP);

kill(pid_t(process->pid()), SIGCONT);

暂停/恢复进程。

但是,一旦完成,进程就不能再被终止,即使是QProcess:kill()。基本上,没有QProcess::waitForFinished() 成功并且进程变成僵尸。

有人知道这是什么原因吗?有什么解决办法吗?

注意:我尝试了this question 的答案,但没有帮助。我在 Mac 上执行此操作,但谷歌搜索表明问题也发生在 Linux 上。

【问题讨论】:

  • 您能否提供一个重现问题的minimal reproducible example。因为我不确定为什么停止/启动的进程应该与其他进程有任何不同。
  • 我添加了an example。似乎一个暂停/恢复的过程不会引起足够多的问题,但是一旦包含第二个,事情就会出错。
  • 可能会分离,在这种情况下您需要对进程进行系统扫描。
  • 我仍然可以向/从进程发送/接收消息 - 如果进程被分离,是否有可能?并且该进程不会继续运行,它会变成僵尸。另外,该进程是否会被信号分离?
  • 我创建了一个小的 bash 脚本 (while true; do sleep(2); done)。有了这个,您提供的示例在两种变体中都适用于我(w 和 w/o 过程 2)。在m_process->kill() 之后,m_process->waitForFinished(1000) 立即返回并且程序打印0: exited。没有僵尸进程。也许问题出在您的从属进程上?

标签: qt unix signals


【解决方案1】:

一般来说,当 SIGSTOP 和随后的 SIGCONT 被发送到进程时,会发生很多事情。停止进程时,相关进程(例如子进程或父进程)不会共同停止。这可能会导致奇怪的异常,例如管道中断或导致超时的延迟。所以总的来说,这些信号没有得到很好的支持。只有对于非常简单的架构(没有分叉、没有子进程等),它们才应该起作用。此外,由于进程可以对 SIGCONT 做出反应,因此任何框架(如 QT)都可能这样做并重新初始化它的一些设施。当然,这也是有道理的,因为在停止之后,有些事情可能已经发生了变化,否则在发生变化时可能已经注意到了。

不幸的是,这种情况非常罕见,并且包含了许多不同的方面,因此通常没有完全测试覆盖,因此与同一个库的其他部分相比,很可能出现错误。我假设您刚刚在 QT 代码中发现了一个问题,或者该框架不支持这些信号。你有任何文件说明它应该吗?

你现在可以做的步骤:

  • 在相关库的错误跟踪系统中搜索已提交的错误报告。
  • 创建一个 mcve 来显示问题。
  • 如果未提交任何内容,请提交错误报告;-)

但我不希望库的维护者会很快做出反应,如果有的话。正如我所说,在更复杂的场景中通常不支持 SIGSTOP 和 SIGCONT。它们的含义太复杂了。

【讨论】: