QApplication之后清理

问题描述 投票:3回答:1

我正在将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的构造函数之前,仅存在一个线程,即主线程,正如预期的那样。
  • 运行QApplication的构造函数后,将另外创建4个线程:
    • QXcbEventQueue
    • gmain
    • gdbus
    • QDBusConnection
  • 运行QApplication的析构函数后,QXcbEventQueue线程消失。
  • 即使在完成第二次10秒钟的睡眠后,除主剧院外的其他3个线程仍然处于活动状态:
    • gmain
    • gdbus
    • QDBusConnection

我正在寻找一种方法,在QApplication完成之后(当然,在实际应用中,我调用app.exec(),以适当地结束这些线程(并进行目前可能不知道的其他清理)。并做其他事情)并已被摧毁。

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

该应用程序是一整套较大的库/其他应用程序的一部分,已使用Google Test进行了全面测试,并且这些测试包括一些Death Tests,如果在运行了一些涉及运行QApplication的测试后执行了这些测试,则会抱怨分叉了可能是因为这个原因,具有多个线程的应用程序会卡住并且永远无法完成。

关于如何在QApplication之后可以摆脱那些线程并执行完全清除的任何提示?

linux multithreading qt googletest qapplication
1个回答
4
投票

我正在寻找正确结束这些线程的方法

简短回答。

您不能

长回答。

[销毁QApplication之后仍保持活动状态的那些线程肯定是由QApplication创建的,但是那些线程是用分离模式on创建的。 See了解更多信息。当以分离模式on创建任何线程时,它既不能加入也不能设置回可加入的状态。

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

现在解决问题。

检查this

两种死亡测试样式的原因与线程安全性有关。由于存在线程时派生的众所周知的问题,死亡测试应在单线程上下文中运行

所以google-test库开发人员非常了解您面临的问题,他们也为这种情况提供了解决方案。看here

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

© www.soinside.com 2019 - 2024. All rights reserved.