在Linux / Qt中我有一个GUI应用程序。 GUI使用QProcess启动其他子进程。要关闭子进程,我使用QProcess :: close()。
QProcess :: close()是否会提升子流程的unix SIGTERM信号?
(我已经链接到QProcess和close()的Qt文档,因为我无法从文档中看出是否引发了unix信号......)
更新:更改问题以询问特定的unix信号:SIGTERM。
答案 0 :(得分:3)
今天我发现QProcess :: close()不会引发SIGTERM信号。为了调试这个问题,我正在捕获子进程的stderr和stdout。 Spoiler:QProcess :: terminate()会引发SIGTERM信号。
处理unix SIGTERM信号的子进程代码:
static void unixSignalHandler(int signum) {
qDebug("DBG: main.cpp::unixSignalHandler(). signal = %s\n", strsignal(signum));
/*
* Make sure your Qt application gracefully quits.
* NOTE - purpose for calling qApp->exit(0):
* 1. Forces the Qt framework's "main event loop `qApp->exec()`" to quit looping.
* 2. Also emits the QCoreApplication::aboutToQuit() signal. This signal is used for cleanup code.
*/
qApp->exit(0);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MAINOBJECT mainobject;
/*
* Setup UNIX signal handlers for some of the common signals.
* NOTE common signals:
* SIGINT: The user started the process on the command line and user ctrl-C.
* SIGTERM: The user kills the process using the `kill` command.
* OR
* The process is started using QProcess and SIGTERM is
* issued when QProcess::close() is used to close the process.
*/
if (signal(SIGINT, unixSignalHandler) == SIG_ERR) {
qFatal("ERR - %s(%d): An error occurred while setting a signal handler.\n", __FILE__,__LINE__);
}
if (signal(SIGTERM, unixSignalHandler) == SIG_ERR) {
qFatal("ERR - %s(%d): An error occurred while setting a signal handler.\n", __FILE__,__LINE__);
}
// executes mainbobject.cleanupSlot() when the Qt framework emits aboutToQuit() signal.
QObject::connect(qApp, SIGNAL(aboutToQuit()),
&mainobject, SLOT(cleanupSlot()));
return a.exec();
}
处理子项的close()或terminate()的父流程代码:
if(this->childProcess1!=NULL && this->childProcess1->state()==QProcess::Running) {
this->childProcess1->terminate(); // raise unix SIGTERM signal on the process (let's it execute cleanup code)
if(childProcess1->waitForFinished() == false) {
qDebug("DBG - MainWindow::close(): Failed to close childProcess1.");
qDebug() << "DBG - childProcess1->exitCode =" << childProcess1->exitCode();
qDebug() << "DBG - childProcess1->ExitStatus =" << childProcess1->exitStatus();
qDebug() << "DBG - childProcess1->error() =" << childProcess1->error();
qDebug() << "DBG - childProcess1->errorString()=" << childProcess1->errorString();
}
}
if(this->childProcess2!=NULL && this->childProcess2->state()== QProcess::Running) {
this->childProcess2->terminate(); // raise unix SIGTERM signal on the process (let's it execute cleanup code)
if(childProcess2->waitForFinished() == false) {
qDebug("DBG - MainWindow::close(): Failed to close childProcess2.");
qDebug() << "DBG - childProcess2->exitCode =" << childProcess2->exitCode();
qDebug() << "DBG - childProcess2->ExitStatus =" << childProcess2->exitStatus();
qDebug() << "DBG - childProcess2->error() =" << childProcess2->error();
qDebug() << "DBG - childProcess2->errorString()=" << childProcess2->errorString();
}
}
当父级使用QProcess::terminate()
时,子进程输出为:
"DBG: main.cpp::unixSignalHandler(). signal = Terminated
当父级使用`QProcess :: close()时,子进程输出为:
DBG - PARENTOBJECT::close(): Failed to close childProcess.
DBG - childProcess->exitCode = 0
DBG - childProcess->ExitStatus = 1
DBG - childProcess->error() = 1
DBG - childProcess->errorString()= "Unknown error"
terminate()
实验的输出证明子进程正在获取SIGTERM信号。
close()
实验的输出证明子进程没有得到SIGTERM信号。
如果要向子进程发送SIGTERM信号,请使用QProcess :: terminate()。
答案 1 :(得分:2)
确实如此,我正在查看qprocess.cpp的源代码,它会通过一些动作很好地将进程调低,然后调用一个通用处理程序,然后传递给qprocess_unix中的terminateProcess,这是SIGTERM的进程。