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 的构造函数 运行 之前,正如预期的那样,只有一个线程,即主线程存在。
- 在 QApplication 的构造函数 运行 之后,创建了 4 个额外的线程:
- QXcbEventQueue
- gmain
- gdbus
- QDBusConnection
- QApplication的析构函数运行后,QXcbEventQueue线程走掉
- 即使在 10 秒的第二次睡眠完成后,除了主线程之外,其他 3 个线程仍然存在:
- gmain
- gdbus
- QDBusConnection
我正在寻找一种方法来在 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
我相信这会对你有所帮助。
我正在将 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 测试进行了彻底测试,并且测试包括一些死亡测试,如果在 运行 一些之后执行涉及 运行 一个 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
我相信这会对你有所帮助。