如何通知线程在应用程序退出时关闭,而主事件循环仍在旋转

时间:2018-11-27 00:58:52

标签: c++ multithreading qt

这是针对以下问题的后续问题: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()

1 个答案:

答案 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实例(没有涉及aboutToQuitQApplication::processEvents的黑客)。 / p>