Qt中QThread安全退出方式总结
创始人
2024-01-20 21:20:05
0

QThread的使用方式
在Qt中,使用QThread实现子线程的方式有两种:

继承QThread,重写run函数
继承QObject,使用moveToThread方式移动进QThread
QThread的退出方式
QThread::terminate() - 不安全
官方说明:
终止线程的执行。线程可以立即终止,也可以不立即终止,这取决于操作系统的调度策略。请在terminate()之后使用QThread::wait()。
当线程终止时,所有等待该线程完成的线程将被唤醒。
警告:此函数是危险的,不鼓励使用。线程可以在其代码路径中的任何点终止。线程可以在修改数据时终止。线程没有机会自己清理,解锁任何持有的互斥锁等。简而言之,只有在绝对必要时才使用这个函数。
终止可以通过调用QThread::setTerminationEnabled()显式地启用或禁用。在终止被禁用时调用此函数将导致延迟终止,直到重新启用终止。有关更多信息,请参阅QThread::setTerminationEnabled()的文档。
我非常不建议大家使用这个函数,一旦使用这个函数,将会对我们的程序造成隐患,这在大型工程中是致命性的

QThread::exit(int returnCode = 0) - 正确使用才安全
官方说明:
用返回代码告诉线程的事件循环退出。
调用此函数后,线程离开事件循环并从QEventLoop::exec()调用中返回。函数的作用是:返回returnCode。
按照惯例,returnCode为0表示成功,任何非零值表示错误。
注意,与同名的C库函数不同,这个函数确实返回给调用者——停止的是事件处理。
在QThread::exec()被再次调用之前,QEventLoops将不会在这个线程中启动。如果QThread::exec()中的eventloop没有运行,那么下一次调用QThread::exec()也会立即返回

QThread::quit - 正确使用才安全
官方说明:
告诉线程的事件循环退出,返回代码为0(成功)。相当于调用QThread::exit(0)。
如果线程没有事件循环,则此函数不执行任何操作。

关于Qt事件循环的文章https://zhuanlan.zhihu.com/p/72758194

QThread安全退出
重写run函数的方式退出,这个我们好控制。但是使用moveToThread的方式,在退出线程的时候,多数同学经常会碰到异常崩溃的情况,基本上都是报错 Destroyed while thread is still running ,说明线程还没有退出事件循环就被强制释放了资源,造成了崩溃。

例如使用了以下的代码(thread初始化方是 new QThread)释放资源

    thread->quit();
    delete thread;

或者使用了以下代码

    thread->terminate();
    delete thread;

这两段代码都是非常不安全的代码,不要使用。

安全的退出方式
使用QThread的finished信号绑定QObject的deleteLater函数实现资源自动释放,也可以绑定一个函数。退出时只需要调用quit()函数即可,如果绑定的是函数,则可以在适当的位置释放thread对象和Object对象
deleteLater函数可以查看Qt文档,这里就不做说明了

线程创建以及退出示例
创建
    TestObject* object = new TestObject;
    QThread* thread = new QThread;
    object->moveToThread(thread );
    connect(thread,&QThread::finished,object,&TestObject::deleteLater);    // 退出后释放TestObject对象资源
    connect(thread,&QThread::finished,thread,&QThread::deleteLater);    // 退出后释放QThread对象资源
    thread->start();

退出
    thread->quit();    // 也可以使用thread->exit(0);
    thread->wait();
    thread = nullptr;
    object = nullptr;

在适当的位置将 thread 和 object 置为nullptr,这样程序就安全了
 

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...