qt - QProcess::close() 是否会在进程上引发 unix SIGTERM 信号?

标签 qt unix process signals

在 Linux/Qt 中我有一个 GUI 应用程序。 GUI 使用 QProcess 启动其他子进程。要关闭子进程,我使用 QProcess::close()。

QProcess::close()为子进程引发 unix SIGTERM 信号?

(我已链接到 QProcess 和 close() 的 Qt 文档,因为我无法从文档中判断是否引发了 unix 信号...)

更新:更改问题以询问特定的 unix 信号:SIGTERM。

最佳答案

今天我发现 QProcess::close() 不会引发 SIGTERM 信号。为了调试这个问题,我捕获了子进程的 stderr 和 stdout。 剧透: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()。

关于qt - QProcess::close() 是否会在进程上引发 unix SIGTERM 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7501762/

相关文章:

java - cat Unix命令直接来自java,不应该调用shell脚本

C# 运行 Windows 窗体应用程序不以窗体开头

python - 识别正在传输 icmp 数据包的进程的 PID

linux - 用不同的语言运行 Qt 应用程序?

c++ - 如何使用 QTreeView 获取有关所选项目的详细信息?

perl - 计算包含数十万个文件的目录中文件数量的最快方法

c - 将 fork 进程输出重定向到 NULL

c++ - 如何构建 Qt Quick 2d 渲染器?

c++ - 如何使用 QModelIndex 访问 QStandardItemModel 及其数据?

bash - unzip 命令中的 Shell 脚本语言帮助