【Qt】多线程QRunnable

news/2024/11/22 22:47:22/

用法

要使用QRunnable创建线程,步骤如下:

  • 继承QRunnable。和QThread使用一样,首先需要将你的线程类继承于QRunnable。
  • 重写run函数。还是和QThread一样,需要重写run函数,run是一个纯虚函数,必须重写。
  • 使用QThreadPool启动线程。

和QThread的区别

与外界通信方式不同。由于QThread是继承于QObject的,所以可以在线程类中使用信号槽,但QRunnable没有继承于QObject,所以不能使用信号与槽。

启动线程方式不同。QThread线程可以直接调用start()函数启动,而QRunnable线程需要借助QThreadPool进行启动。

资源管理不同。QThread线程对象需要手动去管理删除和释放,而QRunnable则会在QThreadPool调用完成后自动释放。

#ifndef CUSRUNNABLE_H
#define CUSRUNNABLE_H#include <QRunnable>class CusRunnable : public QRunnable
{
public:CusRunnable();~CusRunnable();void run() override;
};#endif // CUSRUNNABLE_H
#include "cusrunnable.h"
#include <QDebug>
#include <QThread>
CusRunnable::CusRunnable()
{}CusRunnable::~CusRunnable()
{qDebug()<<"~CusRunnable";
}void CusRunnable::run()
{for(int i=0;i<10;i++){qDebug()<<"doWork %d"<<i<<" thread_id"<<QThread::currentThreadId();QThread::sleep(1);}
}
    CusRunnable* run=new CusRunnable();qDebug()<<"main thread_id="<<QThread::currentThreadId();QThreadPool::globalInstance()->start(run);
main thread_id= 0x7004
doWork %d 0  thread_id 0x6228
doWork %d 1  thread_id 0x6228
doWork %d 2  thread_id 0x6228
doWork %d 3  thread_id 0x6228
doWork %d 4  thread_id 0x6228
doWork %d 5  thread_id 0x6228
doWork %d 6  thread_id 0x6228
doWork %d 7  thread_id 0x6228
doWork %d 8  thread_id 0x6228
doWork %d 9  thread_id 0x6228
~CusRunnable

启动线程方式

上面说到启动QRunnable线程需要QThreadPool,而调用方式有两种:全局线程池和非全局线程池。

全局线程池如上面示例中。非全局线程池其实就是自己实例化一个QThreadPool对象,我们可以控制线程最大数量等。

    CusRunnable* run=new CusRunnable();qDebug()<<"main thread_id="<<QThread::currentThreadId();QThreadPool pool;pool.start(run);

与外界通信

因为QRunnable没有继承于QObject,所以没法使用信号与槽。QRunnable与外界通信有两种方式:

  • 使用多继承。让自定义的线程类同时继承于QRunnable和QObject,这样就可以使用信号与槽了,但是项目中尽量少用多继承。
  • 使用QMetaObject::invokeMethod

QMetaObject::invokeMethod

函数定义如下:

[static] bool QMetaObject::invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument( Q_NULLPTR ), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument())

该函数就是尝试调用obj的member函数,可以是信号、槽或者Q_INVOKABLE声明的函数(能够被Qt元对象系统唤起),如果调用成功,返回true,失败返回false。
QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式Qt::ConnectionType type。如果type为Qt::DirectConnection,则为同步调用,若为Qt::QueuedConnection,则为异步调用。

首先,我们在使用CusRunnable类的类中定义如下函数:

Q_INVOKABLE  void onResultReady(const QString result);void SIHToolBar::onResultReady(const QString result)
{qDebug()<<"onResultReady result="<<result<<" thread_id="<<QThread::currentThreadId();
}

然后,我们想要在CusRunnable类中调用这个函数,就需要这个这个函数的对象。所以,我们实例化CusRunnable的时候,把该对象传进去。

CusRunnable(QObject* obj);

最后,我们在run函数中调用这个对象的函数。

void CusRunnable::run()
{for(int i=0;i<10;i++){qDebug()<<"doWork %d"<<i<<" thread_id"<<QThread::currentThreadId();QThread::sleep(1);}QMetaObject::invokeMethod(obj,"onResultReady",Q_ARG(QString,"hello"));
}

http://www.ppmy.cn/news/144493.html

相关文章

反编译未加固代码(Mac)

反编译未加固代码&#xff08;Mac&#xff09; 一、将 dex 转成 jar1.1、下载dex2jar1.2、拖 apk 到如上文件夹1.3、dex 生成 jar 二、将 jar 转成 java2.1、下载 JD-GUI2.2、下载 jdk2.3、使用 参考地址 一、将 dex 转成 jar 1.1、下载dex2jar https://github.com/pxb1988/d…

群狼调研开展某品牌家电销售渠道调查

群狼调研开展某品牌家电销售渠道调查 群狼调研受某品牌家电委托开展销售渠道调查&#xff0c;帮助客户了解其销售渠道管理现状&#xff0c;提升渠道管理能力。 该家电品牌专注于高端嵌入式厨房电器的研发和制造&#xff0c;拥有吸油烟机、嵌入式灶具、嵌入式消毒柜、嵌入式微…

油烟机买顶吸还是侧吸?三大对比找答案

厨房承载着一个家庭的一日三餐&#xff0c;但也是油烟的“聚集地”&#xff0c;油烟机选不对&#xff0c;家人难免会受到油烟的侵害。油烟机可以分为顶吸式和侧吸式&#xff0c;那么油烟机买顶吸还是侧吸好呢&#xff1f;下面通过三大对比来找答案吧&#xff01; 油烟机买顶吸…

【干货】2014年值得仔细研究的十大神级文案

2014年对于广告文案界来说是最具争议的一年&#xff1b;广告不再是单纯的视觉享受&#xff0c;文案的力量越来越不可忽视&#xff1b;任何一个话题都能轻易上头条&#xff0c;让群众热议很久。正是因为给予了文案工作者更大的篇幅&#xff0c;更广泛的创作环境&#xff0c;才会…

中国创业者十大素质

《科学投资》研究了国内上千例创业者案例&#xff0c;发现国内创业者基本可以分成以下几种 类型。 第一种类型&#xff1a;生存型创业者。创业者大多为下岗工人、失去土地或因为种种原因不愿困守乡村的农民&#xff0c;以及刚刚毕业找不到工作的大学生。这是中国数量最大的一拨…

智选假日酒店品牌创立三十周年;首家汉庭新品旗舰店落子天津;百胜中国西南供应链支持中心落户成都 | 美通企业周刊...

一周企业资讯看点&#xff1a;智选假日酒店迎品牌三十周年。首家汉庭新品旗舰店落子天津。美的智能家电搭载华为鸿蒙系统产品将大批量上市。奥特斯投资约2亿欧元&#xff0c;进一步提升重庆工厂ABF载板产能。卡瓦集团上海总部创新卓越中心正式启动。强生全视旗下可同时矫正视力…

跨国整合多品牌 海尔智能家居实现全球协同

2017中国家电及消费电子博览会&#xff08;AWE2017&#xff09;今天落幕&#xff0c;海尔产品成为收获了最多的奖项&#xff0c;还收获了更多的人气&#xff0c;从海尔六大家电品牌全球化战略&#xff0c;到智能家居系统及单品&#xff0c;项目个个亮眼。 海尔全球化家电 品牌集…

集成灶哪个品牌性价比高质量好,最全集成灶测评来啦

购买厨房电器我们都追求性价比&#xff0c;而这里的性价比指的是符合自己经济和产品质量需求的正对比&#xff0c;因为大家都希望用符合自己预算的钱去购买到靠谱的集成灶产品。 集成灶哪个品牌性价比高质量好&#xff1f;我花了一个月的时间去体验和整理出这个问题的答案&…