简体   繁体   English

通过 unix 信号优雅地终止 Qt 应用程序

[英]Graceful termination of Qt application by unix signal

I have problems saving settings in my application.我在我的应用程序中保存设置时遇到问题。 This is done in the destructors of the relevant objects.这是在相关对象的析构函数中完成的。 It is a launcher and a termination by shutdown is a standard case.它是一个启动器,通过关闭终止是标准情况。 The only way the application actually saves the setting is by manual closing it or session shutdown (on cinnamon at least, I guess this just closes all windows).应用程序实际保存设置的唯一方法是手动关闭它或关闭会话(至少在肉桂上,我猜这只会关闭所有窗口)。 Even sudo reboot prevents the Qt application from unwinding the objects on the stack.即使sudo reboot也会阻止 Qt 应用程序展开堆栈上的对象。 Terminating by killall -s <signal> <app> has the same effect for SIGINT , SIGKILL and SIGTERM .通过killall -s <signal> <app>终止对SIGINTSIGKILLSIGTERM具有相同的效果。 How can I force my qt app to gracefully terminate at on SIGTERM ?如何强制我的 qt 应用程序在SIGTERM上正常终止? aboutToQuit is not emitted either. aboutToQuit也不会发出。

There is a minimal set of functions a unix signal handler is allowed to call. Unix 信号处理程序允许调用的最小函数集。 They are called async-signal-safe functions.它们被称为异步信号安全函数。 Calling everything else, including every Qt function, results in undefined behavior.调用其他所有内容,包括每个 Qt 函数,都会导致未定义的行为。

Still there is a way to handle unix signals in Qt.仍然有一种方法可以在 Qt 中处理 unix 信号。 The way uses the self-pipe-trick and is described in the Qt docs article "Calling Qt Functions From Unix Signal Handlers" .该方法使用自管道技巧,并在 Qt 文档文章“从 Unix 信号处理程序调用 Qt 函数”中进行了描述

Basically you open a pipe and whenever you get a signal you ::write(...) (this is a async-signal-safe function) to the pipe.基本上你打开一个管道,每当你收到信号时,你::write(...) (这是一个异步信号安全函数)到管道。 On the other end you listen to the pipe using a QSocketNotifier .在另一端,您使用QSocketNotifier收听管道。 For the implementation details check the Qt article mentioned above.有关实现细节,请查看上面提到的 Qt 文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM