Qt moveToThread

简介: Qt moveToThread

moveToThread位于QObject中,官方对此函数的解释如下:

void QObject::moveToThread(QThread *targetThread)

Changes the thread affinity for this object and its children. The object cannot be moved if it has a parent. Event processing will continue in the targetThread.


这个函数适合于QObject及其子类,并且QObject的父对象必须为空,否则移动到线程失败。移动成功后,将在目标线程中开启事件处理。

待移动到线程的Object

// 耗时操作具体执行的类
class Worker : public QObject
{
    Q_OBJECT
public:
    Worker(QObject* parent = 0);
    virtual ~Worker();
signals:
    void sglProgress(int val); // 进度信号,[0, 100],指示进度
    void sglFinished(); // 结束信号
public slots:
    // 开始执行耗时操作的槽函数,结束后调用deleteLater(),析构自己
    void start();
};

启动类

void FrmMain::sltWork()
{
    Worker* worker = new Worker(0); // parent 需为0
    // 连接耗时操作进度和完成信号对应的槽函数
    connect(worker, SIGNAL(sglProgress(int)), this, SLOT(sltProgress(int)));
    connect(worker, SIGNAL(sglFinished()), this, SLOT(sltFinished()));
    QThread* thread = new QThread(0); // 开启一个新线程
    worker->moveToThread(thread);
    // worker需在线程启动后开启,这也是耗时操作的start()函数是槽函数的原因
    connect(thread, SIGNAL(started()), worker, SLOT(start()));
    // 耗时操作完成后,线程退出
    connect(worker, SIGNAL(sglFinished()), thread, SLOT(quit()));
    // 特别说明(1),看后面详细说明
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    // 启动线程
    thread->start();
}

防止内存泄漏,需要使用deleteLater()函数析构thread,常见的一个bug是这样造成的

connect(worker, SIGNAL(sglFinished()), thread, SLOT(deleteLater()));

看上去好像也没什么,其实,会是一个很不稳定的因素,如果线程相对简单,可以很快quit掉,程序仿佛可以正常运行,而事实上并不总是这样,以为worker的sglFinished()信号同时连接了thread的quit()和deleteLater()两个槽函数,如果quit()还没执行完成时,就执行deleteLater(),会造成软件的崩,或者Destroyed while thread is still running这样的bug()。因此,sglFinished()信号连接了线程quit()函数,线程正常退出后,会释放finished()信号,然后由finished()信号连接线程的deleteLater()槽函数,会使线程安全的退出并析构。


参考:

1、Qt 多线程之QObject::moveToThread

2、简单说说对QT中moveToThread实现多线程操作的理解

3、Qt线程实现分析-moveToThread vs 继承

目录
相关文章
|
存储 安全 算法
Qt QSet 详解:从底层原理到高级用法
Qt QSet 详解:从底层原理到高级用法
1947 0
|
Ubuntu Linux 编译器
openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
3395 0
|
移动开发
Qt自定义控件之仪表盘的完整实现
Qt自定义控件之仪表盘的完整实现
|
Java 调度 Python
深入解析 Python asyncio 库:如何使用线程池实现高效异步编程
深入解析 Python asyncio 库:如何使用线程池实现高效异步编程
1190 0
|
8月前
|
编解码 Linux iOS开发
轻松录制你的Linux桌面(新手也能快速上手的录屏教程)
教程来源https://www.vps5.cn/本文介绍两款Linux系统下优秀的免费录屏软件:功能强大的OBS Studio和简单易用的SimpleScreenRecorder,涵盖安装步骤、使用方法及常见问题解答,帮助用户轻松录制教学视频、游戏或会议内容。
|
存储
Qt使用 QSetting 对 ini 配置文件进行操作
Qt使用 QSetting 对 ini 配置文件进行操作
1841 0
|
前端开发 测试技术 API
Apifox 深度评测:你应该使用的 API 管理工具
Apifox是一款强大的API管理工具,集API设计、开发、测试和文档管理于一体,有效解决传统工具分散导致的效率低下和信息不一致问题。它提供直观界面定义API接口,自动生成文档,支持数据模型管理及迭代分支功能。此外,Apifox具备Mock服务、强大的调试工具和自动化测试能力,还能进行性能测试评估API在高负载下的表现。其文档管理功能支持版本控制和变更历史追踪,便于团队协作与分享。Apifox的优势在于一体化解决方案和简洁直观的用户界面,相较于Postman和Swagger等竞品,在功能整合和易用性方面表现出色。总之,Apifox为API全生命周期管理提供了全面支持,极大提升了开发效率。
|
存储 监控 图形学
【QT】GraphicsView、QGraphicsScene、QGraphicsEllipseItem的使用
【QT】GraphicsView、QGraphicsScene、QGraphicsEllipseItem的使用
1634 0
《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用
《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用
3352 1
《QT从基础到进阶·二十一》QGraphicsView、QGraphicsScene和QGraphicsItem坐标关系和应用

热门文章

最新文章