关于QT线程运用的三种方式

2023-05-16

QThread 类函数

// QThread 类常用 API
// 构造函数
QThread::QThread(QObject *parent = Q_NULLPTR);
// 判断线程中的任务是不是处理完毕了
bool QThread::isFinished() const;
// 判断子线程是不是在执行任务
bool QThread::isRunning() const;

// Qt中的线程可以设置优先级
// 得到当前线程的优先级
Priority QThread::priority() const;
void QThread::setPriority(Priority priority);
优先级:
    QThread::IdlePriority         --> 最低的优先级
    QThread::LowestPriority
    QThread::LowPriority
    QThread::NormalPriority
    QThread::HighPriority
    QThread::HighestPriority
    QThread::TimeCriticalPriority --> 最高的优先级
    QThread::InheritPriority      --> 子线程和其父线程的优先级相同, 默认是这个
// 退出线程, 停止底层的事件循环
// 退出线程的工作函数
void QThread::exit(int returnCode = 0);
// 调用线程退出函数之后, 线程不会马上退出因为当前任务有可能还没有完成, 调回用这个函数是
// 等待任务完成, 然后退出线程, 一般情况下会在 exit() 后边调用这个函数
bool QThread::wait(unsigned long time = ULONG_MAX);

// 子线程要处理什么任务, 需要写到 run() 中
[virtual protected] void QThread::run();

// 返回一个指向管理当前执行线程的QThread的指针
[static] QThread *QThread::currentThread();
// 返回可以在系统上运行的理想线程数 == 和当前电脑的 CPU 核心数相同
[static] int QThread::idealThreadCount();
// 线程休眠函数
[static] void QThread::msleep(unsigned long msecs);	// 单位: 毫秒
[static] void QThread::sleep(unsigned long secs);	// 单位: 秒
[static] void QThread::usleep(unsigned long usecs);	// 单位: 微秒

第一种 继承QThread  重写run方法

class MyThread:public QThread
{
    ......
 protected:
    void run()
    {
        ........
    }
}

在主线程中创建子线程对象,new 一个就可以了

MyThread * subThread = new MyThread;

启动子线程,调用 start () 方法

subThread->start();

第二种   MoveToThread()  函数。        Qt 提供的第二种线程的创建方式弥补了第一种方式的缺点,用起来更加灵活,但是这种方式写起来会相对复杂一些

创建一个新的类,让这个类从 QObject 派生

class MyWork:public QObject
{
    .......
}

在这个类中添加一个公共的成员函数,函数体就是我们要子线程中执行的业务逻辑

class MyWork:public QObject
{
public:
    .......
    // 函数名自己指定, 叫什么都可以, 参数可以根据实际需求添加
    void working();
}

在主线程中创建一个 QThread 对象,这就是子线程的对象

QThread* sub = new QThread;

在主线程中创建工作的类对象(千万不要指定给创建的对象指定父对象

MyWork* work = new MyWork(this);    // error
MyWork* work = new MyWork;          // ok


将 MyWork 对象移动到创建的子线程对象中,
需要调用 QObject 类提供的 moveToThread() 方法

// void QObject::moveToThread(QThread *targetThread);
// 如果给work指定了父对象, 这个函数调用就失败了
// 提示: QObject::moveToThread: Cannot move objects with a parent
work->moveToThread(sub);	// 移动到子线程中工作


启动子线程,调用 start(), 这时候线程启动了,但是移动到线程中的对象并没有工作

调用 MyWork 类对象的工作函数,让这个函数开始执行,这时候是在移动到的那个子线程中运行的

第三种 采用线程池 QThreadPool 

在 Qt 中使用线程池需要先创建任务,添加到线程池中的每一个任务都需要是一个 QRunnable 类型,因此在程序中需要创建子类继承 QRunnable 这个类,然后重写 run() 方法,在这个函数中编写要在线程池中执行的任务,并将这个子类对象传递给线程池,这样任务就可以被线程池中的某个工作的线程处理掉了。

QRunnable 类 常用函数不多,主要是设置任务对象传给线程池后,是否需要自动析构。

// 在子类中必须要重写的函数, 里边是任务的处理流程
[pure virtual] void QRunnable::run();

// 参数设置为 true: 这个任务对象在线程池中的线程中处理完毕, 这个任务对象就会自动销毁
// 参数设置为 false: 这个任务对象在线程池中的线程中处理完毕, 对象需要程序猿手动销毁
void QRunnable::setAutoDelete(bool autoDelete);
// 获取当前任务对象的析构方式,返回true->自动析构, 返回false->手动析构
bool QRunnable::autoDelete() const;

创建一个要添加到线程池中的任务类,处理方式如下:

class MyWork : public QObject, public QRunnable
{
    Q_OBJECT
public:
    explicit MyWork(QObject *parent = nullptr)
    {
        // 任务执行完毕,该对象自动销毁
        setAutoDelete(true);
    }
    ~MyWork();

    void run() override{}
}

在上面的示例中 MyWork 类是一个多重继承,如果需要在这个任务中使用 Qt 的信号槽机制进行数据的传递就必须继承 QObject 这个类,如果不使用信号槽传递数据就可以不继承了,只继承 QRunnable 即可。

class MyWork :public QRunnable
{
    Q_OBJECT
public:
    explicit MyWork()
    {
        // 任务执行完毕,该对象自动销毁
        setAutoDelete(true);
    }
    ~MyWork();

    void run() override{}
}


线程池常用的 API 函数如下:

// 获取和设置线程中的最大线程个数
int maxThreadCount() const;
void setMaxThreadCount(int maxThreadCount);

// 给线程池添加任务, 任务是一个 QRunnable 类型的对象
// 如果线程池中没有空闲的线程了, 任务会放到任务队列中, 等待线程处理
void QThreadPool::start(QRunnable * runnable, int priority = 0);
// 如果线程池中没有空闲的线程了, 直接返回值, 任务添加失败, 任务不会添加到任务队列中
bool QThreadPool::tryStart(QRunnable * runnable);

// 线程池中被激活的线程的个数(正在工作的线程个数)
int QThreadPool::activeThreadCount() const;

// 尝试性的将某一个任务从线程池的任务队列中删除, 如果任务已经开始执行就无法删除了
bool QThreadPool::tryTake(QRunnable *runnable);
// 将线程池中的任务队列里边没有开始处理的所有任务删除, 如果已经开始处理了就无法通过该函数删除了
void QThreadPool::clear();

// 在每个Qt应用程序中都有一个全局的线程池对象, 通过这个函数直接访问这个对象
static QThreadPool * QThreadPool::globalInstance();

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于QT线程运用的三种方式 的相关文章

  • Ubuntu安装code-server

    span class token function apt span span class token function install span code server 安装完成 输入命令 code server
  • Docker下安装mysql超详细步骤

    查看需要安装的镜像版本 dockerHub官网地址 搜索mysql 2 点击标签 3 点击Tags 查看想要的版本号 在安装好docker的linux中执行命令 拉取mysql最新版本 span class token function d
  • (java)实现将随机字符串中的字符升序排列,降序打印

    题目要求 xff1a 实现将随机字符串中的字符升序排列 xff0c 降序打印 如何进行升序排列 xff1f xff1a sort 必须是一个数组 xff0c 才能使用Arrays sort方法 String变成数组 xff0c 用toCha
  • UI自动化之获取设备号及package

    span class token comment coding 61 utf 8 span span class token keyword import span os span class token punctuation span
  • Verilog 代码编写 状态机-序列检测

    题目 xff1a 有一种特殊的串行通信系统 xff0c 数据以包的形式传输 xff0c 数据的包头为 01111110 xff0c 然后为数据内容 xff0c 然后 01111110 结尾 xff0c 现在需要编写程序 xff0c 完成数据
  • 电脑相机不能使用,出现的灰色画面上有一个相机标志加一斜杠的解决办法

    64 TOC 电脑相机不能使用 xff0c 出现的灰色画面上有一个相机标志加一斜杠的解决办法 这是我第一次发博客 xff0c 写的不好 xff0c 请见谅 因为我也出现过这个问题 xff0c 依照网上搜索的方法去尝试 xff0c 但是都没有
  • Github Copilot的申请及在Pycharm的配置和使用

    文章目录 目录Github Copilot的申请及在Pycharm的配置和使用2022 06 29更新1 简介2 copilot首页3 copilot的申请4 GitHub Copilot 官方使用文档5 PyChram下载地址6 Pych
  • C语言程序设计(第五章 数组)

    C语言程序设计 xff08 第五章 数组 xff09 1 一维数组 xff08 1 xff09 数组是一组有序数据的集合 xff08 2 xff09 用一个数组名 xff08 如s xff09 和下标 xff08 如15 xff09 来唯一
  • CCF计算机软件能力认证202112-1序列查询(C语言版)

    ccf csp计算机软件能力认证202112 1序列查询 C语言版 题目内容 xff1a 试题背景 问题描述 输入格式 输出格式 样例1输入 span class token number 3 span span class token n
  • c#第一天

    Net Net 平台 和 Net FrameWork 框架 xff1a Net FrameWork 框架 xff08 CLR 公共语言运行时 xff0c Net 类库 xff09 交互模式 C S xff1a 客户机 Client 服务器
  • Java输入数判断是否为回文数

    最近看黑马的Java 顺带做了些课后练习 xff0c 感觉代码还是得自己多打打 xff0c 记录比较简陋 import java util Scanner public class HuiWeng public static void ma
  • copilot申请使用流程(自用)

    整体流程 1 申请github学生包 申请网址 xff1a https education github com 2 copilot学生申请 申请网址 xff1a https copilot github com 3 IDE下载插件配置 下
  • 在VMware Workstation以及云服务器上安装华为FusionCompute

    文章目录 前言使用镜像安装CNAVMware Workstation配置虚拟机步骤一步骤二步骤三步骤四步骤五步骤六步骤七步骤八步骤九步骤十步骤十一步骤十二步骤十二 云服务器远程登录CNA安装步骤一 xff1a 开始安装步骤二 xff1a 配
  • 华为FusionCompute:虚拟机创建与配置

    文章目录 前言创建裸虚拟机删除虚拟机导入虚拟机虚拟机规格调整CPU热添加内存热添加磁盘扩容添加网卡查看 虚拟机配置对象权限 前言 如何在CNA中创建虚拟机 xff0c 创建虚拟机的方法有多种 创建的好的虚拟机我们可以进行虚拟机规格的调整 x
  • Postman接口之token获取及数据关联和断言

    1 环境变量的创建及使用 2 变量名设置 xff0c 点击上一步的环境变量 xff0c 弹出下面的页面 xff1a 3 设置完后记得选择对应的环境变量 4 查看接口运行后参数是否存入到环境变量中 xff1a 好了基础设置如上 xff0c 下
  • OSPF(六)OSPF特殊区域之Stub和Totally Stub区域详解及配置

    文章目录 前言Stub区域和Totally Stub区域传输区域和末端网络Stub Area配置命令 Totally Stub Area配置 整体实验配置过程及命令步骤一 xff1a 搭建拓扑步骤二 xff1a 配置路由器接口IP地址步骤三
  • OSPF(二)DR与BDR选举

    文章目录 MA网络中的问题DR amp DBRDR与BDR的选举 MA网络中的问题 在运行OSPF的MA网络包括广播型网络和NBMA网络 xff0c 都会存在两个问题 在一个有n个路由器的网络 xff0c 会形成 n n 1 2个邻接关系
  • 防火墙详解(三)华为防火墙基础安全策略配置(命令行配置)

    实验要求 根据实验要求配置防火墙 xff1a 合理部署防火墙安全策略以及安全区域实现内网用户可以访问外网用户 xff0c 反之不能访问内网用户和外网用户均可以访问公司服务器 实验配置 步骤一 xff1a 配置各个终端 防火墙端口IP地址 终
  • 常见信息安全威胁与经典案例

    文章目录 信息安全威胁现状网络战争的开端 xff1a 震网 病毒信息安全攻击事件的演变安全威胁分类 网络安全威胁案例美国Dyn DNS服务遭受DDoS攻击Mirai病毒发动攻击过程 xff08 DDos攻击过程 xff09 扫描获取控制权限
  • 华为FusionCompute详解(一)FusionSphere虚拟化套件介绍

    文章目录 虚拟化FusionSphere虚拟化套件特点管理简单性能至优 FusionSphere虚拟化套件组成FusionSphere服务器虚拟化架构FusionSphere架构特点与用途FusionSphere应用场景单虚拟化场景多虚拟化

随机推荐

  • 华为FusionCompute详解(二)FusionCompute总体介绍以及规划部署

    文章目录 FusionCompute产品定位FusionCompute产品架构FusionCompute软件逻辑组成 FusionCompute产品功能虚拟化计算虚拟化存储虚拟化网络 FusionCompute带来的价值FusionComp
  • Docker基础篇(1)

    文章目录 Docker简介是什么概念容器VS虚拟机能干什么技术职级变化一次构建 xff08 镜像 xff09 xff0c 到处运行 xff1a 去哪下 Docker简介 是什么 为什么会有Docker出现 xff1a 解决重复的环境部署开销
  • openStack:学习openStack的前提知识(1)虚拟化以及KVM简介

    文章目录 KVM简介KVM核心组件Libvirt组件 KVM简介 KVM 目前X86平台上最热门 xff0c 运用最多的虚拟化解决方案 xff0c openStack对KVM支持也是最好的 所以后续使用KVM作为Hypervisor xff
  • 解决WSL2/ubuntu安装软件报错 E: Invalid operation insatll 问题

    文章目录 解决WSL2安装软件报错E Invalid operation insatll 问题方法一方法二 解决WSL2安装软件报错E Invalid operation insatll 问题 此问题为系统定位不到软件包 xff0c 无法安
  • github-copilot的使用步骤

    1 首先登录你的github账号 xff0c 点击头像 xff0c 点击设置 2 在设置界面点击Copilot 并点击try Colilot 3 点击绿色按钮继续 4 设置为允许 xff0c 并取消允许使用你的代码来改进这一选项 xff0c
  • Arduino IDE配置esp8266开发环境

    目录 前言arduino IDE安装配置ESP8266开发环境通过开发板管理器安装手动安装开发版管理器备用的网址 参考 前言 之前本科那会疫情在家用esp8266 ESP 01s Relay模块做了一个远程浇花的设备 xff0c 当时使用a
  • 三、Ubuntu 18.04系统调试(命令/换源)

    目录 一 常用命令 二 Ubuntu 18 04换源 2 1便捷方法 2 2命令行方法 xff08 较为复杂 xff0c 但可查看防止后期有些错误是因为源导致的源文件 xff09 一 常用命令 目录操作 pwd 查看当前目录 cd 返回上一
  • 使用VScode远程操作虚拟机(ubuntu)

    1 VSCode安装 2 打开Ubuntu 使用ifconfig 获取系统接口 3 打开remote ssh 4 配置好相关属性 5 开启远程连接输入密码即可连接
  • 学习率(Learing Rate)的作用以及如何调整

    1 什么是学习率 学习率 Learning rate 作为监督学习以及深度学习中重要的超参 xff0c 其决定着目标函数能否收敛到局部最小值以及何时收敛到最小值 合适的学习率能够使目标函数在合适的时间内收敛到局部最小值 这里以梯度下降为例
  • Pytorch 中net.train() 和 net.eval()的作用和如何使用?

    一般在训练模型的代码段加入 xff1a model train 在测试模型时候加入 xff1a model eval 同时发现 xff0c 如果不写这两个程序也可以运行 xff0c 这是因为这两个方法是针对在网络训练和测试时采用不同方式的情
  • Qt 子窗口内嵌到父窗口中

    有时需要把一个子窗口内嵌进入父窗口当中 我们可以这样做 1 新建一个QWidget 或者QDialog的子类 ClassA xff08 父类为ClassB xff09 2 在新建类的构造函数中添加设置窗口属性 setWindowFlags
  • 用Cmake 编译OpenCV常见的错误

    minGW32 make遇到的错误1 xff1a 37 Linking CXX shared library bin libopencv core341 dll CMakeFiles opencv core dir objects a me
  • 卷积 反卷积 上采样 下采样 区别

    1 卷积 就是利用卷积核 步长前进 卷积整个图片 2 反卷积 反卷积的具体操作 原图输入尺寸为 1 xff0c 3 xff0c 3 xff0c 3 对应 batch size channels width height 反卷积tconv 6
  • Go语言操作数据库MySQL

    连接 Go语言中的database sql包提供了保证SQL或类SQL数据库的泛用接口 xff0c 并不提供具体的数据库驱动 使用database sql包时必须注入 xff08 至少 xff09 一个数据库驱动 我们常用的数据库基本上都有
  • 解决Git请求错误问题

    git clone gits github com Cloning into 39 FdogSerialize 39 git 39 remote gits 39 is not a git command See 39 git help 39
  • Reactor 模式

    Reactor 翻译过来的意思是 反应堆 xff0c 可能大家会联想到物理学里的核反应堆 xff0c 实际上并不是的这个意思 这里的反应指的是 对事件反应 xff0c 也就是来了一个事件 xff0c Reactor 就有相对应的反应 响应
  • MATLAB画图调整分辨率

    问题 xff1a 经常需要用MATLAB画图 xff0c 但是保存之后分辨率不高 xff0c 特别是需要放大的情况下 解决 xff1a 对于下面这种画出的图形 选择 文件 61 gt 导出设置 61 gt 渲染 61 gt 分辨率 选择60
  • C语言中常见的逻辑错误

    常见错误一 xff1a 61 和 61 61 混在一起 int main int ret if ret 61 1 return 0 结果 xff1a 变量被错误赋值 xff0c 逻辑判断错误 错误二 xff1a 定义较大的全局变量造成 编译
  • Qt中常见的位置和尺寸

    QPoint类的介绍 QPoint 类封装了我们常用用到的坐标点 x y 常用的 API 如下 构造函数 构造一个坐标原点 即 0 0 QPoint QPoint 参数为 x轴坐标 y轴坐标 QPoint QPoint int xpos i
  • 关于QT线程运用的三种方式

    QThread 类函数 QThread 类常用 API 构造函数 QThread QThread QObject parent 61 Q NULLPTR 判断线程中的任务是不是处理完毕了 bool QThread isFinished co