无法关闭 QThread - 应用程序崩溃

Posted

技术标签:

【中文标题】无法关闭 QThread - 应用程序崩溃【英文标题】:cant close QThread - Application crashes 【发布时间】:2015-11-10 14:54:18 【问题描述】:

我有一个带有工作线程的应用程序。当我尝试停止线程并关闭我的应用程序时,它崩溃了。

我正在创建工作线程和线程并将信号和插槽连接为:

QPointer<QThread> monitorThread(new QThread());
QPointer<ItemMonitor> monitor(new ItemMonitor(items));
monitor->moveToThread(monitorThread);

//closeInitiated signal emitted when custom close button is clicked
connect(this, SIGNAL(closeInitiated()), monitor, SLOT(finishUp()));
connect(monitor, SIGNAL(finished()), monitorThread, SLOT(quit()));
connect(monitor, SIGNAL(finished()), monitor, SLOT(deleteLater()));
connect(monitor, SIGNAL(finished()), this, SLOT(closeApplication()));
connect(monitorThread, SIGNAL(started()), monitor, SLOT(beginMonitoring()));
connect(monitorThread, SIGNAL(finished()), monitorThread, SLOT(deleteLater()));

//start monitoring
monitorThread->start();

QThread中运行的ItemMonitor类是

#include "itemmonitor.h"
#include "todoitem.h"
#include <QObject>
#include <iostream>
#include <QTimer>


ItemMonitor::ItemMonitor(std::vector< QPointer<ToDoItem> >& items_)
:items(items_),
 shouldRun(true)
    std::cout << "Monitor created" << std::endl;



void ItemMonitor::beginMonitoring()
    if(shouldRun)
        for(int i=0; i<items.size(); i++)
            items[i]->setSecsTillDeadline();
        
        QTimer::singleShot(100, this, SLOT(beginMonitoring()));
    else
        emit finished();
    


void ItemMonitor::finishUp()
    shouldRun = false;

我的主类中的 closeApplication 函数是:

void ToDoList::closeApplication()
    while(monitorThread->isRunning())
        std:: cout << "thread not closed" << std::endl;
    
    QApplication::quit();

对我来说奇怪的是,如果我没有尝试退出线程而只是尝试关闭应用程序,那么就没有错误

【问题讨论】:

您可以在这里调用“connect(monitor, SIGNAL(finished()), this, SLOT(closeApplication()));”如果您在清理应用程序时删除,可能会导致问题。您是否尝试关闭应用程序两次?我看不到您尝试在关闭函数中停止线程的位置。 “崩溃”毫无意义。至少,您应该查看堆栈跟踪。 当我尝试在 qt 调试器中调试应用程序时,它永远不会运行并冻结我的整个计算机...我必须重新启动,所以我看不到堆栈跟踪 我没有尝试在关闭函数中关闭线程。正在从监视器完成()信号调用线程退出槽 【参考方案1】:
connect(monitor, SIGNAL(finished()), monitorThread, SLOT(quit()));
connect(monitorThread, SIGNAL(finished()), monitorThread, SLOT(deleteLater()));

monitor emit finished() -> monitorThread->quit() -> monitorThread 发出finished() -> monitorThread->deleteLater() 在监视器发出finished() 信号后,monitorThread 将被删除。

void ToDoList::closeApplication()
    while(monitorThread->isRunning())//maybe you should check the monitorThread for null
        std:: cout << "thread not closed" << std::endl;
    
    QApplication::quit();

【讨论】:

以上是关于无法关闭 QThread - 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 macOS 上使用 QThread 时 PyQt 应用程序崩溃或挂起?

也许 QThread 中的 QTLineEdit 范围会导致程序崩溃?

使用 Pyside2 QThread 线程化时,Scipy curve_fit 崩溃

[ PyQt入门教程 ] PyQt5中多线程模块QThread使用方法

QThread 转储核心

PySide2 Qthread 崩溃