QT踩坑第十一天(QT多线程)

2023-11-17

前言:
QT在什么时候会用到多线程:
所有的IO操作都要放到线程里面
1、IO操作QIODevice文件IO网络IO(套接字eg:CAN Linux下也是套接字)串口等外设,因为他们不确定什么时候可以读完。
2、耗时的算法eg:文件压缩 信号处理
注意:
1、线程里面尽量少用while(1)+sleep();
尽量使用事件驱动,少用耗时扫描
并发控制简介:
进行时间片轮流:比如让xx执行0.000001秒只要来回转可以看见N多软件一起在“转”;这样让用户看起来都在执行;
实时抢占:严格按照优先级走,优先级高的能抢占优先级低的任务(线程);

一、QThread介绍

QThread类提供了一个与平台无关的线程管理的方法。一个QThread对象管理一个线程。QThread的执行
从run()函数的执行开始,在QT自带的QThread类中,run()函数通 过调用exec()函数来启动事件循环机制,,并且在线程内部处理Qt的事件。在Qt中建立 线程的主要目的就是为了用线程来处理那些耗时的后台操作,从而让主界面能及时响应用户的请求操作。
QThread的使用方法有如下两种:
QObject::moveToThread()
继承QThread类

二、演示线程

2.1 如何创建线程
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
默认情况,我们新建的类(除少部分外),不支持信号与槽
在class中添加一个Q_OBJECT
在这里插入图片描述
左边的类不支持信号与槽;需要手动添加 Q_OBJECT
继承QThread类的线程框架:
在这里插入图片描述
头文件:

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread();
    void setThreadName(QString name);
protected:
    virtual void run();
private:
    QString ThreadName;
};

myThread.cpp:

#include "myThread.h"
MyThread::MyThread()
{
 qDebug() << ThreadName <<  "MyThread::MyThread" << QThread::currentThreadId();
}
void MyThread::setThreadName(QString name)
{
    ThreadName=name;
    qDebug()<<ThreadName<<"    My Thread::setThreadName:"<<QThread::currentThreadId();
}
void MyThread::run()
{
    
    while(1)
    {
       qDebug()<<ThreadName<<"    My Thread::run():"<<QThread::currentThreadId();
         sleep(1);
    }
}

main.cpp:

#include <QCoreApplication>
#include"myThread.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //开辟了四个线程
    MyThread thread1;
    thread1.setThreadName("thread1");
    thread1.start();
    MyThread thread2;
    thread2.setThreadName("thread2");
    thread2.start();
    MyThread thread3;
    thread3.setThreadName("thread3");
    thread3.start();
    MyThread thread4;
    thread4.setThreadName("thread4");
    thread4.start();
    return a.exec();
}

在这里插入图片描述
2.2 演示线程ID
QThread::currentThreadId();
在这里插入图片描述
结论:只有run里面才属于线程本身(自线程),其他的都是父线程的。
信号与槽的接口:
在这里插入图片描述
2.3如何让线程保活
run情况下:
while(1)sleep
exec;
2.4 演示线程退出
如何优雅的退出线程:
以md5CheckSumToolsThread为例:
在这里插入图片描述
主线程关闭时,子线程生命周期还没有结束的话,就会报如下的错误 —— 经典报错对 话框:
在这里插入图片描述
线程退出 exit() terminate()
线程等等 wait

Widget::~Widget() 
{     
md5Thread.exit();                 //线程退出    
 qDebug() << QTime::currentTime();     
md5Thread.wait(10 * 1000 );       //10秒超时 (阻塞的时间最大是 10s) 
qDebug() << QTime::currentTime(); //确定wait的时间    
 delete ui; 
}

2.5 演示信号与槽中的第五个参数
connect一直都是4个参数,在这里又怎么出第五个参数了? 一般情况,第五个参数只 有在多线程中使用 通过第五个参数演示默认连接方式 多线程讲这个才有意义,不然都是空中楼阁不好理解 。
connect原型:
QObject::connect(const QObject sender, const char signal, const QObject receiver,const char method, Qt::ConnectionType type = Qt::AutoConnection)

方式 描述
Qt::AutoConnection 0 默认参数;自动连接, 自动选择是Direct或者Queued
Qt::DirectConnection 1 槽函数立即执行,槽函数所在的发送者线程中执行
-
Qt::QueuedConnection 2 槽函数排队(队列)执行,槽函数在接收者所在的线程中
Qt::BlockingQueuedConnection 3 阻塞式排队连接
-
Qt::UniqueConnection 4 一对一的自动连接

这只是个人理解,可能有些地方不正确,大家遇到此类需求可以参考官方文档
在这里插入图片描述
上图为多线程中信号与槽中的经典错误。
2.6 线程锁QMutex(一种线程的安全方式)
QMutex类提供了一种保护一个变量或者一段代码的方法,这样可以每次只让一个线程 访问它。这个类提供了一个lock()函数用于锁住互斥量,如果互斥量是解锁状态,那么 当前线程立即占用并锁定它;否则,当前线程会阻塞,直到这个互斥量的线程对它解 锁为止。QMutex类还提供了一个tryLock()函数,如果该互斥量已经锁定,它就会立即 返回。
Qt帮助文档演示QMutex
在这里插入图片描述在这里插入图片描述
创建两个线程:

mythread.h

  #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include<QThread>
    #include<QMutex>
    #include<qDebug>
    class MyThread : public QThread
    {
        Q_OBJECT
    public:
        MyThread();
        void setThreadName(QString name);
    protected:
        virtual void run();
    private:
        QString ThreadName;
    };

main.cpp

#include <QCoreApplication>
#include"mythread.h"
 int globalIndex;
 QMutex globelMutex;
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyThread thread1;
    thread1.setThreadName("thread1");
    thread1.start();

    MyThread thread2;
    thread2.setThreadName("thread2");
    thread2.start();
    return a.exec();
}

mythread.cpp

#include "mythread.h"
extern int globalIndex;
extern Mutex globelMutex;
MyThread::MyThread()
{

}
 void MyThread::setThreadName(QString name)
 {
     ThreadName=name;
 }
 void MyThread::run()
 {
     while(1)
     {
         //globelMutex.lock();
         globalIndex++;
         qDebug()<<ThreadName<<globalIndex<<&gloleMutex;
        // globelMutex.unlock();
         sleep(1);
     }
 }

当线程没有加锁的时候:
在这里插入图片描述
我们希望的是每个线程给index+1,把持好节奏访问同一段公共资源,需要Mutex
准备锁:
在什么情况下会用到锁?
第一种情况:是设备的IO设备 socket写一个东西(多线程保证按照顺序来写)
第二种情况:全部变量,多个线程访问一个全局变量。

QMutex globelMutex;

修改run

 void MyThread::run()
 {
     while(1)
     {
         globelMutex.lock();
         globalIndex++;
         qDebug()<<ThreadName<<globalIndex<<&gloleMutex;
        globelMutex.unlock();
         sleep(1);
     }
 }

在这里插入图片描述
锁这{}锁必须是同一把锁:所以这里用了globelMutex

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

QT踩坑第十一天(QT多线程) 的相关文章

  • 没有DOI,只有卷期号时的IEEE期刊论文查找方法

    未给出DOI时的IEEE论文查询方法 登录IEEE 选择期刊查询 寻找对应期刊 寻找对应年份 卷 期 页 登录IEEE 首先登录IEEE官网 使用校园网登录才可以直接查看下载论文 链接 IEEE官网 选择期刊查询 寻找对应期刊 寻找对应年份
  • 2023荣耀校招机试 解数独

    题目描述 数独根据9 9盘面上的已知数字 推理出所有乘余空格的的数字并满足每一行 每一列 每一个格子内数字均含1 9 不重复 每一道合格的数独谜题都有且仅有唯一答案 推理方法也以此为基础 任何无解或多解的题目都是不合格的 即所有空格的数据只
  • SpeedTree导入Unity解决方案

    微软的Note笔记 和网页编辑不能很好复制 这里没有图 建议查看另一个链接 https onenote com webapp pages token KxEyAkijcfJZgzOF30PAPkVySHIcjsPyhrE5wkJoK9KTI
  • 计算机必知必会:进程process与线程thread

    进程和线程这对概念的理解也是很难的 至今网络上可查的资料对其的理解出入都挺大 在不同的操作系统中 如linux和windows中 其概念和实现都是有出入的 因此 我在这里结合我自己的理解谈下这两个概念 讲的都是一般性的概念 并且主要是基以W
  • pandas报错:columns overlap but no suffix specified

    使用pandas的join连接两张表 例如表1是left 表2是right 这两张表都有共同的字段user name 我就以user name这个字段连接这两张表 left join right how left on user name
  • 2018.09.29 学习笔记 // 前端Javascript // 日期、Math、数组与对象API

    题目 答案见后面 获取2018 09 29格式的日期 获取随机数 要求是长度一直的字符串格式 写一个能遍历对象的数组的通用forEach函数 日期和Math var a Date now 获取当前时间毫秒数 从1970年到现在走了多少毫秒
  • 使用Matlab实现基于计算机视觉的DIP芯片缺陷检测系统附带GUI界面

    使用Matlab实现基于计算机视觉的DIP芯片缺陷检测系统附带GUI界面 计算机视觉在工业生产中的应用越来越广泛 其中一项重要的应用是对芯片制造过程中的缺陷进行检测 本文将介绍如何使用Matlab实现一个基于计算机视觉的DIP芯片缺陷检测系
  • pythonnone赋值-【零基础学Python】def语句,参数和None值

    像之前的print input 和len 功能 Python提供了一些类似的内置函数 另外也可以自己编写自定义函数 示例 def hello print Howdy print Howdy print Hello there hello 第
  • 刷脸支付商户流水不断服务商收益不断

    刷脸支付的管道红利 刷脸支付是获利的其实刷脸支付的商业模式本质上也是一种管道收入 通过一家商户的流水得到佣金 十家商户 N家商户 开通刷脸支付的商户越多 佣金就越多 可以赚取的收益也就越多 就正如管道一样 只要商家在营业 那么你的收入就源源
  • 初识数据库-mysql

    初识数据库 不同的数据库 sql语句不一样 总体大致差不多 数据存储的简短回顾 在内存中临时存储数据所需 变量 数组 长度不可变 类型太单一 对象 对象数组 近乎解决了数组类型太单一的问题 集合 解决了数组长度不可变 持久存储数据 I O
  • 应用层协议 --- DNS协议

    DNS Domain Name Service 域名服务 DNS协议基于UDP 使用端口号53 由数字组成的 IP 地址很难记忆 所以我们上网使用网站 IP 地址的别名 域名 实际使用中 域名与 IP 地址是对应的 这种对应关系保存在DNS
  • 【前端面经】JS-如何使用 JavaScript 来判断用户设备类型?

    在 Web 开发中 有时需要针对不同的设备类型进行不同的处理 例如 对于移动设备 我们可能需要采用不同的布局或者交互方式 以提供更好的用户体验 因此 如何判断用户设备类型成为了一个重要的问题 1 使用 navigator userAgent
  • python优雅地爬虫

    申明 仅用作学习用途 不提供任何的商业价值 背景 我需要获得新闻 然后tts 在每天上班的路上可以听一下 具体的方案后期我也会做一次分享 先看我喜欢的万能的老路 获得html内容 gt python的工具库解析 获得元素中的内容 完成 好家
  • 『Newsletter丨第一期』PieCloudDB 新增自动启停、预聚集、试用规则优化、费用中心等多项功能模块...

    第一部分 PieCloudDB 最新动态 PieCloudDB 完成多个产品兼容性认证 PieCloudDB 与多家基础架构软件厂商完成产品兼容性认证 类别包括操作系统 服务器 CPU 云平台 新增 8 家生态伙伴 包括龙蜥 麒麟 中科可控
  • c语言求fibonacci数列前20,求fibonacci数列的前20个数之和

    使用数组求Fibonacci数列的前20项 要求4项一行输出 斐波那契数列通项公式 斐波那契数列指的是这样一个数列 1 1 2 3 5 8 13 21 这个数列从第三项开始 每一项都等于前两项之和 includeintmain inta 2
  • 容斥原理——经典例题(组合数学)

    一 容斥原理 就是人们为了不重复计算重叠部分 想出的一种不重复计算的方法 先来认识一下这两个符号 与 如图 蓝色的圈就是c1c2 红色的圈围起来的就是c1c2 二 例题 组合数学 1 题目 1 1 题目描述 八是个很有趣的数字啊 八 发 八
  • Centos nginx配置文档

    1 安装nginx yum install nginx 2 Nginx常用命令 查看版本 nginx v 启动 nginx c etc nginx nginx conf 重新加载配置 nginx s reload 停止 nginx s st
  • Bat批处理使用ren批量重命名文件,比如批量去掉文件名称的前4位

    从手机下导入一批照片到电脑 照片开头都是以IMG 开头 甚是烦 使用ren可以批量去掉IMG 开头的几个字符 参考如下 去掉文件名称的最前面4位 去掉文件名称的最后5位 去掉的5位包括 jpg这四个后缀 echo off Deep Lee
  • OCR文字检测主要算法

    转载 https www mayi888 com archives 60604 文字检测是文字识别过程中的一个非常重要的环节 文字检测的主要目标是将图片中的文字区域位置检测出来 以便于进行后面的文字识别 只有找到了文本所在区域 才能对其内容
  • 西门子 PLC S7单边通信

    PLC通信 1 组态 编程 1 打开博途软件 创建新项目 命名为 通信 2 添加新设备 命名为A 这里选择的是CPU1211C 版本V4 2 3 CPU属性设置 启用系统存储器字节和时钟存储器字节 4 以太网地址设置 IP地址设为 192

随机推荐

  • 一文说明白SMC继电器的三种模式:迟滞模式,窗口模式,报警模式

    阅读时间5分钟 有不少同学表示 不理解迟滞模式 窗口模式 报警模式 这里花点儿时间说明一下 这三种模式按照难易程度 1 报警模式 这种方式顾名思义 到压力报警 回到正常范围 报警消除 简单易懂 不过 如果我们需要的压力是0 7MPa 那么我
  • Java坑人面试题系列: 变量声明(中级难度)

    作用域规则与变量覆盖面试题 Java Magazine上面有一个专门坑人的面试题系列 https blogs oracle com javamagazine quiz 2 这些问题的设计宗旨 主要是测试面试者对Java语言的了解程度 而不是
  • 华为OD -单词接龙(Python)

    单词接龙 题目描述 单词接龙的规则是 可用于接龙的单词 首字母必须要与前一个单词的尾字母相同 当存在多个首字母相同的单词时 取长度最长的单词 如果长度也相等 则取字典序最小的单词 已经参与接龙的单词不能重复使用 现给定一组全部由小写字母组成
  • vue+element-ui el-descriptions 详情渲染组件二次封装(Vue项目)

    目录 1 需求 2 想要的效果就是由图一变成图二 编辑 3 组件集成了以下功能 4 参数配置 示例代码 参数说明 5 组件 6 页面使用 1 需求 一般后台管理系统 通常页面都有增删改查 而查不外乎就是渲染新增 修改的数据 由输入框变成输入
  • Oracle 数据库查看锁表的语句和解锁的方法

    一 查看锁表语句 SELECT sess sid sess serial lo oracle username 登陆账号名称 lo os user name 登录电脑名称 ao object name 被锁表名 lo locked mode
  • 【Vulnhub】之symfonos1

    一 部署方法 在官网上下载靶机ova环境 https download vulnhub com symfonos symfonos1 7z 使用VMware搭建靶机环境 攻击机使用VMware上搭建的kali 靶机和攻击机之间使用NAT模式
  • oracle impdp无法打开日志文件,oracle expdp导入时 提示“ORA-39002: 操作无效 ORA-39070: 无法打开日志文件 ”...

    oracle impdp导入时 提示 OpenCurlyDoubleQuote ORA 39002 colon 操作无效 ORA 39070 colon 无法打开日志文件 第一步 首先使用DBA权限的用户创建directory 我使用sys
  • ‘git‘不是内部或外部命令,也不是可运行的程序或批处理文件。

    一 出现问题 git 不是内部或外部命令 也不是可运行的程序或批处理文件 出现这个问题主要是git的环境变量没有设置 二 解决问题 首先右键我的电脑点击属性 在点击高级系统设置 点击环境变量 在下面这栏点击path设置环境变量 添加这三个环
  • 【人工智能】感知器算法的设计实现(QDU)

    人工智能 Astar算法求解8数码问题 QDU 人工智能 利用 搜索的博弈树算法编写一字棋游戏 QDU 人工智能 Fisher 线性分类器的设计与实现 QDU 人工智能 感知器算法的设计实现 QDU 人工智能 SVM 分类器的设计与应用 Q
  • Hive的数据类型

    Hive支持的数据类型如下 原生类型 TINYINT SMALLINT INT BIGINT BOOLEAN FLOAT DOUBLE STRING BINARY Hive 0 8 0以上才可用 TIMESTAMP Hive 0 8 0以上
  • 04-SpringBoot集成Nebula Graph

    SpringBoot集成Nebula 建议模块 在这里给大家推荐一种方式 每引入一种新的技术 建议新建一个模块 来适配这种技术 对外提供接口 在调用的地方应用就可以 不用搞的到处都是 防止如果后续替换这种技术 还要到处修改 这样的话 只需要
  • 工业大数据漫谈14:煤矿与非煤矿矿山如何应用大数据

    在工业领域 煤矿与非煤矿山属于相对特殊的行业 不是我们传统意义上的工厂模式 而是一种资源开采模式 矿山行业因为其生产的特殊性 因此在工业大数据的应用上 也呈现出了与制造型工业完全不同的特点 与制造型工业相比较 矿山行业最大的区别在于产品质量
  • JTest简单试用

    安装JTest 拷贝破解文件lic client jar到 Parasoft Test 9 4 plugins com parasoft xtest libs 9 4 0 20120412 Parasoft 创建附带案例 例如JPetSto
  • SpringBoot项目在IDEA制作Docker镜像并部署到阿里服务器运行

    SpringBoot项目如何在IDEA制作Docker镜像并部署到阿里服务器运行 首先IDEA安装Docker插件 没错就是它 这家伙挺好用的 安装后你会看到 这里就是配置你阿里云服务器地址的 服务器开放docker的2375端口还需要改配
  • Visual Studio error C2001:常量中有换行符

    问题描述 问题分析 经百度多方求助 发现该问题主要是由中文和文件编码格式引起的 存在中文时需要手动文件编码格式转换成UTF 8 这里使用Notepad 去转换 但是很奇怪的是我发现我的文件就是UTF 8的格式 仍然编译不过 我查询了其他没有
  • idea插件生成用例图、时序图、类图、活动图

    给大家推荐一个idea生成用例图 时序图等的神器 PlantUML 最近软件工程要结课了 结课报告要附加用例图 时序图 类图 活动图等 类图我首先就想到可以用idea生成 嘿嘿 可惜忘了怎么用 搜着搜着 突然发现 idea生成时序图 用例图
  • dfs、bfs时候染色算法和直接传一个visited两种方法

    以695 岛屿的最大面积为例 在图的遍历中 如果不加任何约束 DFS和BFS一定会遍历到重复节点 解决这个问题的一个方法就是在函数外定义一个visited set 然后每次遍历的时候把未在visited中的节点加入 在外面的递归终止条件 队
  • eclipse 项目没错却有红叉(解决办法)

    1 进入 eclipse 选择报错的项目 然后在工具栏选择Window 选择Show View 选择Problems 如下图 2 找到 General 下的 problems 双击 problems 就会在下面提示你项目报错的原因 根据错误
  • Go_异常处理

    Error 异常就是程序出现了不正常的情况 会导致程序非正常停止 而异常处理就是针对非正常停止的情况 给出异常时的处理方式 语法错误不算异常体系中 error是一个接口 作用是返回程序异常的信息 errors实现了error type er
  • QT踩坑第十一天(QT多线程)

    前言 QT在什么时候会用到多线程 所有的IO操作都要放到线程里面 1 IO操作QIODevice文件IO网络IO 套接字eg CAN Linux下也是套接字 串口等外设 因为他们不确定什么时候可以读完 2 耗时的算法eg 文件压缩 信号处理