如何确定在Linux上用Qt4终止一个QProcess的信号?

问题描述 投票:0回答:1

我想检测 QProcess 我推出的是由外部终止的任一 SIGKILLSIGTERM. 这对于区分崩溃(bug)和外部干扰是很重要的,当我自己编写了要启动的进程。

我试着通过一个连接到 QProcess::started 并设定一个 SIGCHLD 处理器(使用 sigaction)来捕捉过程状态,使用 waitpid. 问题是: waitpid 清空了内部的内核数据结构,即使我把处理程序正确地链到了在 QProcess 的实现,后者无法获得子女的状态,因为任何下一步对 waitpid 为该pid失败。将进程状态设置为 QProcess::ProcessState::NotRunning 通过 QProcess::setProcessState 避免挂断电话 waitForFinished 但也有一些角落的情况,我还没办法解决。

我想知道,除了修改Qt的源码将状态信息存储在某个地方之外,是否还有更好的方法。

注:我知道崩溃也会用一个信号来终止,这个信号就是 SIGABRT. 这里的主要问题是 SIGKILL 可能会告诉我,Linux中的内存外杀手是导致进程终止的原因。

linux qt4 qprocess sigaction
1个回答
0
投票

这是我的代码,朋友。

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)
{
}

0
投票

改变Qt下的代码的解决方案。Qt 4,基本上涉及到一个简单的修改,以 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::exitCode() 之后 QProcess::finished() 已经发出。

注:Qt5使用了Thiago Macieira的 forkfd所以这个解决方案是行不通的。

© www.soinside.com 2019 - 2024. All rights reserved.