这是针对以下问题的后续问题:QThread is creating a memory leak on application quit。
基本上,我的问题的解决方案包括析构函数:
virtual ~MainWindow() {
delete th; // th = thread handler
QCoreApplication::processEvents(QEventLoop::AllEvents, 500);
}
virtual ~ThreadHandler() {
if (my_thread != Q_NULLPTR && my_thread->isRunning()) {
my_thread->quit();
my_thread->wait();
}
qDebug() << "ThreadHandler Destructor";
}
我不喜欢带有processEvents
的“手动”事件循环,但是如果没有它,则有两次内存泄漏。显然,当我的MainWindow
的析构函数被调用时,主事件循环不再旋转。因此,我将delete th;
命令移到了aboutToQuit()
的{{1}}插槽中,但是最后仍然需要额外的事件循环。如果我读过docs,我会知道事件循环在此事件之前就停止了工作。
在应用程序即将退出主程序时发出此信号 事件循环,例如当事件循环级别降至零时。这可能 从应用程序内部调用quit()之后发生,或者 当用户关闭整个桌面会话时。
问题:
有没有办法在事件循环仍在应用程序末尾删除MainWindow
的情况下?我的意思是,是否有一个信号,例如:“请辞职,然后辞职”。
还是有另一种解决方案来解决这个问题?该线程应始终在后台运行,并且永远不会“结束”。有信号发送给线程,以赋予它新的工作,但是在完成时,线程将只是空闲而不是结束。这是有意的。
我在Qt论坛中发现了this。克里斯·卡瓦:
理想情况下,您将等待所有其他线程完成后再执行 退出主线程中的事件循环。如果你不能做到这一点 我会等其他线程在
ThreadHandler
中完成的原因 处理程序,然后手动调用aboutToQuit()
处理任何内容 这些线程在您退出事件循环后发布。
这还对吗,没有更好的解决方案了?
我在git上有一个minimal, compilable, working example。它太大了,无法发布,而不会因无聊的代码而使所有内容混乱。
这是关键要素:如何设置线程:
processEvents()
答案 0 :(得分:0)
据我所知,您所依赖的事实是应用程序正在退出,以发出退出后台线程的信号,等待它,然后将其删除。为什么在这种情况下需要延迟删除?我认为没有任何理由。
由于ThreadHandler
是创建,启动和结束您的后台线程的类,因此您也应该使它负责删除该线程。只需在ThreadHandler
析构函数中添加以下行(在my_thread->quit();
和my_thread->wait()
之后):
delete my_thread;
这应该是安全的,因为可以确保线程已事先停止。另外,由于您要从析构函数中销毁my_thread
实例,因此现在应从ThreadHandler::startThread()
删除此行:
QObject::connect(my_thread, &QThread::finished, my_thread, &QThread::deleteLater);
在那之后,您可以返回从ThreadHandler
的析构函数中删除MainWindow
实例(没有涉及aboutToQuit
和QApplication::processEvents
的黑客)。 / p>