QApplication 之后的清理

Cleaning up after QApplication

我正在将 Qt 桌面应用程序移植到 Linux(Ubuntu 19.10、64 位桌面、Qt 5.12.5、gcc 版本 9.2.1),并且我看到一些意想不到的线程仍然存在QApplication 完成后。

这是最低重现率:

#include <QApplication>
#include <unistd.h>
int main(int argc, char * argv[]) {
    {
        QApplication app(argc, argv);
        sleep(1);
    }
    sleep(10);
    return 0;
}

如果我在不同的时间点调试应用程序,我会看到以下内容:

我正在寻找一种方法来在 QApplication 完成后(当然,在真正的应用程序中我调用 app.exec() 并做其他事情)并已被销毁。

这不是应用程序本身的问题,在这 3 个线程仍然存在的情况下到达 main 的末尾似乎没有问题。

该应用程序是更大的库/其他应用程序套件的一部分,这些库/其他应用程序已使用 Google 测试进行了彻底测试,并且测试包括一些死亡测试,如果在 运行 一些之后执行涉及 运行 一个 QApplication 的测试,抱怨分叉一个有多个线程的应用程序,并卡住并且永远不会完成,大概是因为这个原因。

关于我如何能够摆脱这些线程并在 QApplication 之后执行完全清理的任何提示?

I'm looking for a way to properly end these threads

简答。

你不能

长答案。

那些在销毁 QApplication are definitely created by QApplication but those threads are created with detached mode on. See 后仍然保持活动状态的线程以获取更多信息。当任何线程以分离模式创建时 on 它既不能加入也不能设置回可加入。

要验证以上检查 this 代码。这是创建所有集成插件的地方。在此处添加断点并在调试期间进入代码(在 GDB 中)。或者您也可以将断点设置为函数 pthread_attr_setdetachstate

现在开始解决问题。

检查 this

The reason for the two death test styles has to do with thread safety. Due to well-known problems with forking in the presence of threads, death tests should be run in a single-threaded context.

所以 google-test 库开发人员很清楚你面临的问题,他们也有针对这种情况的解决方案。看here

我相信这会对你有所帮助。