C++及QT的线程学习

目录

一. 线程学习

二. 学习线程当中,得到的未知。

1. 了解以下MainWindow和main的关系

2. [=]()匿名函数 有函数体,没有函数名.

3. join和detach都是用来管理线程的生命周期的,它们的区别在于线程结束和资源的回收。

4. operator()() 仿函数

5. try-catch的使用以及细节。处理异常,try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。

6. C++创建多线程

1).普通函数的多线程创建方式

2).lsmbda表达式方式创建多线程

3).仿函数方式创建多线程

4).类成员函数创建多线程


一. 线程学习

首先,我们任意建一个QT工程,按下按键让数字递增。

void Widget::on_pushButton_clicked()
{int i = 0;for(;;){ui->lcdNumber->display(QString::number(i++));sleep(1);}
}

但是我们在槽里这样写的话,移动窗口或者按下按键会报错,因为我们既要绘制窗口,又要响应窗口移动的操作,还要执行自加的逻辑,当执行到这个自加的逻辑就已经很忙了,它就没有功夫去调用显示逻辑了。我们可以加一个Debug查看一下。

void Widget::on_pushButton_clicked()
{int i = 0;for(;;){qDebug() << i;ui->lcdNumber->display(QString::number(i++));sleep(1);}
}

可以发现操作台是有数在走的,但是却没有显示。

这时候我们就得采用多线程。那么我们使用join还是detach呢,因为主线程也要执行,不可能等待子线程执行,而且主线程本身就是一个循环,比如return a.exec();主进程不会退出,所以使用detach。

void Widget::on_pushButton_clicked()
{std::thread my_thread(&Widget::showInfo,this);my_thread.detach();
}void Widget::showInfo()
{int i = 0;for(;;){qDebug() << i;ui->lcdNumber->display(QString::number(i++));sleep(1);}
}

因为是在栈中定义的my_thread,所以不需要担心资源回收的问题,函数一结束,my_thread就销毁了,不用担心线程回收的问题。

这样,我们点击按钮开始计数之后就不会卡死。

当然QT中封装了一个多线程的类,叫QThread。刚刚我们写的线程是没有退出的逻辑的,所以接下来我们使用QThread。

定义一个自定义的类,继承QThread并重写run()方法,在里面写线程执行的逻辑,定义一个信号。

#include "my_thrad.h"
#include <QDebug>
My_Thrad::My_Thrad(QObject *parent) : QThread(parent)
{}void My_Thrad::run()
{int i = 0;for(;;){qDebug() << i;emit threadSignal(i++);this->sleep(1);if (i > 10){break;}}
}
#ifndef MY_THRAD_H
#define MY_THRAD_H#include <QThread>
#include <QDebug>
class My_Thrad : public QThread
{Q_OBJECT
public:explicit My_Thrad(QObject *parent = nullptr);~My_Thrad()//析构函数{qDebug() << "线程退出了,并回收了线程空间";}
protected:void run() override;
signals:void threadSignal(int val);
};#endif // MY_THRAD_H

这里我们添加了一个析构函数,是判断新建线程能不能结束,而要保证关闭窗口的时候,线程仍然能够执行,实现一个安全可靠的退出,我们就要:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);my_thread = new My_Thrad(this);//this父对象就是main.cpp中的wconnect(my_thread,&My_Thrad::threadSignal,[=](int val){ui->lcdNumber->display(QString::number(val));});
}Widget::~Widget()
{delete ui;my_thread->exit();my_thread->wait();//等待线程执行完毕,然后才退出delete my_thread;
//   // my_thread->deleteLater();//它是依赖于某个对象,还依赖于主事件循环存在的情况下,才是有效的,所以这样会内存泄露
}void Widget::on_pushButton_clicked()
{my_thread->start();//使用start间接调用的run方法
}

因此我们在~Widget()析构函数中写上述代码,实现等待线程执行完毕,才退出,并删除my_thread,输出”线程退出了,并回收了线程空间。

二. 学习线程当中,得到的未知。

1. 了解以下MainWindow和main的关系

main()函数,非窗体程序入口函数

Mainwindow函数,是窗体程序的入口函数

2. [=]()匿名函数 有函数体,没有函数名.

3. join和detach都是用来管理线程的生命周期的,它们的区别在于线程结束和资源的回收。

join函数会阻塞当前线程,直到被调用join()的线程(子线程)执行完毕并退出,在这个过程中,调用join()的线程会一直等待,直到被等待的线程退出。如果没有调用join函数。被等待的线程退出后,它的资源不会被回收,这可能会导致内存泄漏。

有时候我们不知道是否已经join()系统提供了一个joinable()来判断是否已经join()

使用detach会让线程在后台运行,这就意味着与主线程不能直接交互了,分离后的线程不能join

但使用detach时,要注意主进程运行的时间,不然可能线程还没执行完,主进程就结束了

4. operator()() 仿函数

5. try-catch的使用以及细节。处理异常,try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。

try{
//可疑代码
//将异常生成对象的异常对象传递给catch块
}catch(异常){
//对异常进行处理
}finally{
} //可以没有finally

6. C++创建多线程

1).普通函数的多线程创建方式

#include <thread>
#include <iostream>
#include <unistd.h>
#include <string>
using namespace std;
void showInfo()
{int i = 0;for(;;){cout << i++ << endl;sleep(10000);}
}void print(const string &s)
{cout<<"hello thread!"<<endl;cout<<s<<endl;
}int main()
{/*thread my_thread(&showInfo);my_thread.join();my_thread.detach();*/cout<<"main thread begin!"<< endl;string s = "hello world";thread t(&print,s);//thread t(&print);t.join();cout<<"main thread end!"<<endl;return 0;
}

2).lsmbda表达式方式创建多线程

#include <iostream>
#include <thread>
#include <string>
using namespace std;int main()
{cout<<"main begin"<<endl;thread t([](string s)-> void{cout<<"hello world!"<<endl;cout<<s<<endl;},"abc");t.join();cout<<"main end"<<endl;return 0;
}

3).仿函数方式创建多线程

#include <iostream>
#include <thread>
#include <string>
using namespace std;
class MyThread{
public:void operator()(){cout<<"Hello World!"<<endl;}
};int main()
{cout<<"main begin"<<endl;MyThread mt;thread t(mt);t.join();cout<<"main end"<<endl;return 0;
}

4).类成员函数创建多线程

#include <iostream>
#include <thread>
#include <string>
using namespace std;
class MyThread{
public:void print(const string &s){cout<<"Hello World!"<<endl;cout<<s<<endl;}
};int main()
{cout<<"main begin"<<endl;MyThread mt;thread t(&MyThread::print,&mt,"ac") ;t.join();cout<<"main end"<<endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4G组网三相四线预付费电表-远程集中抄表

安科瑞薛瑶瑶18701709087/17343930412 DTSY1352 三相预付费电能表分别用于计量额定频率50Hz 的单、三相交流有功电能&#xff0c;具有预付费控制、负载控制、时间控制及 RS485 通信等功能&#xff0c;性能指标符合 GB/T17215.321-2008 标准。是改革传统用电体制&#xff0c…

杰理695的UI模式LED灯控制

UI模式LED灯修改每个模式对应的LED灯闪烁修改在ui_normal_status_deal(u8 *status, u8 *power_status, u8 ui_mg_para)

开源克隆声音的项目-OpenVoice V2

myshell的OpenVoice 出v2版本了 只需要上传一段20秒到5分钟之间的声音&#xff0c;就可以克隆声音。 单人讲话 没有背景噪音 时间在20秒至5分钟之间 本地部署我没有做&#xff0c;我在myshell的官网上测试了一下&#xff0c;可能是上传的音频有杂音&#xff0c;导致不是很清…

人机交互系统文本分类 text classification环节源码(E-commerce)

我把pre-trained model 下载到了本地 效果如下&#xff08;到时候把代码中的sequence 和labels换成自己的text和分类就行了。&#xff09;&#xff1a; 源码见链接&#xff1a; https://download.csdn.net/download/qqqweiweiqq/89211553

2024年好用又便宜的云手机!哪款性价比高?

随着科技的飞速发展&#xff0c;云计算技术也在不断演进&#xff0c;而云手机作为其创新之一&#xff0c;已经开始在我们的生活中崭露头角。它通过将手机的硬件和软件功能移到云端&#xff0c;让用户能够借助强大的云计算资源完成各种任务。2024年&#xff0c;哪款云手机性价比…

Ubuntu关闭防火墙、关闭selinux、关闭swap

关闭防火墙 打开终端&#xff0c;然后输入如下命令&#xff0c;查看防火墙状态&#xff1a; sudo ufw status 开启防火墙命令如下&#xff1a; sudo ufw enable 关闭防火墙命令如下&#xff1a; sudo ufw disable 关闭selinux setenforce 0 && sed -i s/SELINUXe…

QML中使用正则表达式

我想在TextField控件中使用正则表达式&#xff0c;然后GPT4给出的回答是这样的&#xff1a; TextField {id: versionInputplaceholderText: qsTr("输入版本号")validator: RegExpValidator { regExp: /^[a-zA-Z0-9]*$/ } // 仅允许字母和数字width: 120 // 设置合…

SpringBoot中多数据源灵活切换解决方案

本篇内容介绍了“SpringBoot中如何使用Dynamic Datasource配置多数据源”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 源码地址/文档说明 功能特性: 支持 数据源分组…

软件设计师-重点的创建型设计模式

一、简单工厂&#xff1a; 简单工厂模式属于创建型模式&#xff0c;但不属于23种设计模式之一。 软考中图 二、工厂方法&#xff1a; 意图&#xff1a; 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。 结…

YOLOV5 TensorRT部署 BatchedNMS(engine模型推理)(下)

主要是在王新宇代码的基础上改进,引入对BatchedNMS的解码 文章目录 1. 修改yolov5.cpp2.修改yololayer.h1. 修改yolov5.cpp 首先增加全局变量,名字根据转onnx时修改的节点名字来,查看onnx文件可以看到,顺序不要弄错。 const char *INPUT_NAME = “images”; const char …

FFmpeg常用结构体、关键函数、ffplay.c分析

一、常用结构体&#xff1a; 1、AVFormatContext结构体&#xff1a; AVFormatContext是一个贯穿全局的数据结构&#xff0c;很多函数都要用它作为参数。FFmpeg代码中对这个数据结构的注释是format I/O context&#xff0c;此结构包含了一个视频流的格式内容。其中存有AVIputFor…

抖音小店值得做吗?前期需要多少资金的投入?

大家好&#xff0c;我是电商糖果 这两天有位想做店的朋友&#xff0c;问了糖果一个问题。 他说开个体店是不是需要办理个体户营业执照。 我回答是的。 他又问办执照是不是需要花钱。 我说自己去工商局办理是免费的&#xff0c;找人代办市场上的价格一般在二百左右。 对方…

最大层内元素和

题目链接 最大层内元素和 题目描述 注意点 返回层内元素之和 最大 的那几层&#xff08;可能只有一层&#xff09;的层号&#xff0c;并返回其中 最小 的那个树中的节点数在 [1, 10000]范围内-10^5 < Node.val < 10^5 解答思路 广度优先遍历树&#xff0c;使用队列存…

应用内竞价(Bidding)技术为什么一定要结合瀑布流广告分层+混合智能排序技术?

应用内竞价&#xff08;In-App Bidding或Header Bidding&#xff09;即在APP端实现竞价的优势显而易见&#xff0c;接入的所有广告平台按价格实时排序&#xff0c;价高者得&#xff0c;这样使得每次广告请求收益都是最大值&#xff0c;从而实现收益最大化。 竞价机制是买卖双方…

改善员工绩效管理的 8 种最佳方法

企业如何改进绩效管理体系&#xff0c;才能获得最好的结果&#xff1f;请仔细阅读&#xff0c;找出答案… 人力资源部门对组织的成功起着至关重要的作用&#xff0c;组织的员工也是如此。更好的组织管理会带来更高的利润。人力资源部门的工作很大一部分就是规范绩效管理体系&a…

19-Echarts 配置系列之: timeline 动态切换

前言&#xff1a; timeline 动态切换 作用&#xff1a;在同一个图表上展示不同时间段的数据&#xff0c;并实现动态切换的效果。 简介原理&#xff1a;在 timeline 中定义显示节点并与相应的数据结构绑定&#xff0c;然后调用 ECharts 提供的方法&#xff0c;重新渲染图表。 …

基于51单片机的天然气检测报警设计

基于51单片机的天然气检测报警 &#xff08;仿真&#xff0b;程序原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.MQ-5检测煤气浓度&#xff1b; 2.浓度分为低、中、高三档&#xff0c;分别用LED灯绿、黄、红来提示&#xff1b; 3.当浓度到达中档…

SpringCloud简介

微服务架构理论 微服务架构概述 Spring Cloud简介Spring Cloud 技术栈SpringBoot和SpringCloud的关系SpringCloud和Dubbo区别对比相关文档 微服务架构概述 微服务是一种架构模式&#xff0c;将单一应用程序划分成一组小的服务&#xff0c;服务之间相互协调、相互配合&#xff0…

chrome浏览器安装elasticsearch的head可视化插件

head插件简介 elasticsearch-head被称为是弹性搜索集群的web前端&#xff0c;head插件主要是用来和elastic Cluster交互的Web前端 head插件历史 elasticsearch-head插件在0.x-2.x版本的时候是集成在elasticsearch内的&#xff0c;由elasticsearch的bin/elasticsearch-plugin…

webpackd打包两次-生成两份代码-出现legacy的js文件

当我们build后dist文件中出现legacy的js文件。 原因&#xff1a; pack.json文件&#xff1b; { *****"browserslist": ["> 0.03%","not dead"] }当我们项目运行在古老的浏览器上面时&#xff08;表示支持市场份额超过 > 0.03% 的浏览器版…