一、线程的一般实现形式

Qt中线程类QThread有2种使用方式。

1.继承自QThread,重写run()

 class MyThread : public QThread{Q_OBJECTprotected:virtual void run() override { ... }};

我们一般在run()中加个死循环,不停处理业务或者调用相关的方法。这样的话,我们的业务逻辑与线程紧密耦合在一起。

适用场景:

用于一直不停处理业务,而不是处理完一单业务后,就可以休眠的这种场景。

2.moveToThread

使用一个QObject作为Worker,并moveToThread到线程上。

此种方式不在本文讨论范围内,故不赘述。

二、抽象业务逻辑

我们的业务是需要挂在线程上跑的,那么业务应该有个可执行接口,以实现挂接到线程上。那简单,来一个接口。

IRunable.h

class IRunable
{public:virtual ~IRunable() {}virtual void exec() = 0;
};

业务,我们也叫它任务,定义2个任务。

class Task1 : public IRunable
{public:virtual void exec() override{qDebug() << "do Task1...";}
};class Task2 : public IRunable
{public:virtual void exec() override{qDebug() << "do Task2...";}
};

我们这里使用的线程类是Thread,它派生于QThread,只不过重写的是Thread::process(),与使用QThread无异。

我们自定义Executor执行器类,继承自Thread,原理是通过addRunable(IRunable *able)添加可执行对象到QList<IRunable *>里面,然后在线程执行函数process()中,依次执行list中的对象。

Executor.cpp

Executor::Executor(QObject *parent): Thread(parent)
{}Executor::~Executor()
{Thread::stop();
}void Executor::addRunable(IRunable *able)
{runableList.append(able);
}void Executor::addRunables(const QList<IRunable *> &ables)
{runableList.append(ables);
}QList<IRunable *> Executor::getRunables()
{return runableList;
}void Executor::process()
{foreach (auto able, runableList){able->exec();}
}

代码比较简单,这样做,可以让任务与线程之间依赖于接口,而不依赖于实现,实现线程与业务逻辑解耦。此后对任务的扩展,不牵涉到线程,且可以实现单线程-多任务,多线程-多任务的灵活配置。

另外,多线程对于共享数据的竞争保护,也可以在各自的任务实现类中,进行处理。

三、测试

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);executor = new Executor();runableList.append(new Task1());runableList.append(new Task2());executor->addRunables(runableList);
}MainWindow::~MainWindow()
{delete executor;executor = nullptr;qDeleteAll(runableList);runableList.clear();delete ui;
}void MainWindow::on_pushButton_start_clicked()
{executor->start();
}void MainWindow::on_pushButton_pause_clicked()
{executor->pause();
}void MainWindow::on_pushButton_stop_clicked()
{executor->stop();
}void MainWindow::on_pushButton_resume_clicked()
{executor->resume();
}void MainWindow::on_pushButton_clicked()
{Thread::State s = executor->state();if (s == Thread::Stoped){qDebug() << "state : Stoped";}else if (s == Thread::Running){qDebug() << "state : Running";}else if (s == Thread::Paused){qDebug() << "state : Paused";}
}

运行效果:


若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:37PauseQThread,即可下载。

QThread之重写run() 实现线程与业务解耦相关推荐

  1. setEvent Qt多线程步骤 基于Qthraed 重写Run函数

    1.创建类基于Qthread,重写run函数 头文件里 class Thread : public QThread{public:P* m_p;bool m_is;bool m_b;Thread(){ ...

  2. QThread使用——关于run和movetoThread的区别

    QThread 使用探讨 2010-10-23 00:30 注意:本文停止更新,请优先考虑 Qt 线程基础(QThread.QtConcurrent等) dbzhang800 2011.06.18 Q ...

  3. 为什么建议 Netty 的 I/O 线程与业务线程分离

    点击上方"芋道源码",选择"置顶公众号" 技术文章第一时间送达! 源码精品专栏 精尽 Dubbo 原理与源码 69 篇 精尽 Netty 原理与源码 61 篇 ...

  4. 如何实现业务解耦?spring中事件监听了解一下

    一.前言 二.业务解耦之事件监听实战         1.事件监听三大组件          2.事件发布以及监听实战案例          3.事件发布以及监听原理 一.前言 耦合这个词在平常的开发 ...

  5. 微信公众号信息推送实现业务解耦

    序 最近第三方服务需要增加微信模板信息推送能力,要与业务系统解耦.微服务架构的springCloud下第三方服务增加能力. 一.技术选型 看了下微信公众号的信息推送开发文档,发现不难,就是一个个接口对 ...

  6. Spring Event 业务解耦神器,刷爆了

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  7. httprunner之业务解耦

    A文件(登录取token被引用文件): # NOTE: Generated By HttpRunner v3.1.8 # FROM: har\.\login.har import allurefrom ...

  8. QThread Qt

    QThread Qt 函数moveToThread() 函数原型: void QObject::moveToThread(QThread *targetThread); 该函数用来改变对象的线程依附性 ...

  9. Java基础 - 坦克大战(第三章,线程基础与线程使用)

    文章目录 本章内容 - 多线程处理 绘制敌方坦克 线程基础 线程相关概念 程序(program) 进程 什么是线程 其他相关概念 单线程 多线程 并发 并行 获取当前电脑处理器(cpu)个数 Java ...

  10. 计算机工作原理及进程和线程的区别

    课前导读: 本篇是关于计算机工作原理和多线程编程的解读,主要包括计算机发展背景.图灵大佬生平.冯诺依曼体系结构.cpu与Gpu.电路门.CPU具体的特点.编程语言.Java的前世今生.操作系统.进程的 ...

最新文章

  1. Scut游戏服务器引擎6.1.5.6发布,直接可运行,支持热更新
  2. 使用python+opencv和pillow以及numpy对图像进行旋转,以及解决图像旋转过程中出现的黑边问题
  3. VTK:可视化之DisplayQuadricSurfaces
  4. ajax中dom,在(jQuery)ajax请求中获取当前脚本DOM对象
  5. 震撼世界的基建狂魔,中国制造的超级工程到底有多牛?
  6. mysql 数据传输 定时,MySQL数据库定时备份的实现方法
  7. Oracle时间函数(转)
  8. Tutorial of Codeforces Round 729 (Div.2)
  9. python 生成testbench_(Testbench用法总结)1. Testbench中文本数据的存储读取操作对比
  10. 8086汇编语言(一) 汇编语言源程序
  11. rss客户端reeder(iphone)使用技巧
  12. 文本数据挖掘实验:文本分类
  13. 如何利用Gmail群发电子邮件
  14. opencv 图像拼接和图像融合技术
  15. MEDA: Meta-Learning with Data Augmentation for Few-Shot Text Classification
  16. 微信为什么使用 SQLite 保存聊天记录
  17. L1-007 念数字(Python3)
  18. DIY一个带WIFI的树莓派照相机
  19. 互联网的战争--腾讯与360
  20. 合并表格文件的简单方法

热门文章

  1. 人声混音处理的基本步骤和常用插件
  2. Android下载文件,如何获取实际的文件名
  3. 计算机管理员权限win8,怎样获取win8.1超级管理员权限
  4. md5加密离线工具windwos,ubuntu
  5. 【从零开始学TVM】三,基于ONNX模型结构了解TVM的前端
  6. word添加自定义样式(导入normal.dotm)
  7. 各大搜索引擎提交入口
  8. 外卖系统源码,如何搭建一套同城o2o外卖商城平台
  9. Win11任务栏怎么变小?Win11任务栏变小的设置方法
  10. Linux下 TP(触摸屏)驱动的框架分析