如何确定在 Linux 上使用 Qt4 终止 QProcess 的信号?
Posted
技术标签:
【中文标题】如何确定在 Linux 上使用 Qt4 终止 QProcess 的信号?【英文标题】:How to determine the signal that terminated a QProcess with Qt4 on Linux? 【发布时间】:2020-09-04 17:56:27 【问题描述】:我想检测我启动的QProcess
是否被SIGKILL
或SIGTERM
外部终止。当我编写自己启动的进程时,这对于区分崩溃(错误)和外部干扰非常重要。
我尝试通过连接到QProcess::started
的插槽注册被监视的进程并设置SIGCHLD
处理程序(使用sigaction
)以使用waitpid
捕获进程状态。问题是waitpid
清除了内部内核数据结构,即使我正确地将我的处理程序链接到QProcess
实现上的那个,后者也无法获得子状态,因为任何下一次调用waitpid
对于那个 pid 失败。将进程状态设置为QProcess::ProcessState::NotRunning
到QProcess::setProcessState
通常可以避免挂起对waitForFinished
的调用,但有些极端情况我还无法修复。
我想知道除了修改 Qt 的源代码以将状态信息存储在某处之外,是否没有更好的方法。
注意:我知道崩溃也会以SIGABRT
的信号终止。这里的主要问题是SIGKILL
可能会告诉我 Linux 中的内存不足杀手是导致进程终止的原因。
【问题讨论】:
【参考方案1】:这是我的代码,朋友。
QProcess* pExe = new QProcess(this);
connect(pExe, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onOSRExit(int, QProcess::ExitStatus)));
pExe->setWorkingDirectory(QCoreApplication::applicationDirPath());
pExe->start("some.exe");
....
void CXXXXX::onOSRExit(int exitCode, QProcess::ExitStatus exitStatus)
【讨论】:
谢谢,但这并不能解决问题。在 Linux 下,我没有收到杀死exitCode
进程的信号。【参考方案2】:
Qt 4下修改Qt代码的解决方案,基本上就是对QProcessPrivate::waitForDeadChild()
的简单修改:
if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0)
processManager()->remove(q);
crashed = !WIFEXITED(exitStatus);
- exitCode = WEXITSTATUS(exitStatus);
+ exitCode = crashed ? WTERMSIG(exitStatus) : WEXITSTATUS(exitStatus);
在发出QProcess::finished()
之后,该信号将在QProcess::exitCode()
上可用。
注意:Qt5 使用的是 Thiago Macieira 的forkfd
,所以这个解决方案不起作用。
【讨论】:
以上是关于如何确定在 Linux 上使用 Qt4 终止 QProcess 的信号?的主要内容,如果未能解决你的问题,请参考以下文章