我在Linux / Qt中启动一个进程,然后使用QProcess启动一些子进程。然后最终我想优雅地关闭子进程(也就是执行一些清理代码)。
子进程正在使用QSharedMemory,现在当我调用QProcess :: close()时子进程正在关闭而不调用QSharedMemory :: detach(),结果是所有进程都关闭了...但是剩余的共享内存未被清理。
我有子进程的代码,代码中有函数cleanup()
。父流程如何以这种方式关闭QProcess,以便子进程执行cleanup()
?
答案 0 :(得分:2)
我让孩子使用unix信号处理程序执行Qt清理代码。
这是一个高级别的解释:
处理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();
}
我confirmed that this solution works。
我认为这是一个很好的解决方案,因为:
kill
命令终止剩余的子进程,并且子进程在关闭之前仍将自行清理简短的回答是因为你做不到。这里解释了为什么你不能在unix信号处理函数中执行你的Qt清理代码。来自Qt documentation "Calling Qt Functions From Unix Signal Handlers":
您无法从Unix信号处理程序调用Qt函数。标准 POSIX规则适用:您只能从中调用异步信号安全函数 信号处理程序。有关完整的功能列表,请参阅Signal Actions 你可以从Unix信号处理程序调用。
答案 1 :(得分:0)
你可以尝试将processExited()信号连接到一个槽来自己处理从共享内存中分离,据我所知,QProcess中没有任何内容可以直接触发分离方法。
答案 2 :(得分:0)
我相信你需要在这里实现一个小协议。您需要一种方法告诉子进程优雅地退出。如果您有两者的来源,您可以尝试使用QtDBus
库来实现这样的信号。