C/C++ 多线程[1]---线程创建+线程释放+实例

文章目录

  • 前言
  • 1. 多线程创建
  • 2. 多线程释放
  • 3. 实例
  • 总结

前言

说来惭愧,写了很久的代码,一个单线程通全部。可能是接触的项目少吧,很多多线程的概念其实都知道,但是实战并没有用上。前段时间给公司软件做一个进度条,涉及到多线程的操作,主要是不影响主线程UI卡死的问题。
这篇博客写一下多线程的一个demo


1. 多线程创建

创建多线程在C++11的标准下使用的是std::thread。

std::thread后面的参数有下面几种:
函数指针或可调用对象(Callable Object):这是新线程要执行的函数或函数对象。可以是函数指针、函数对象、lambda 表达式等。

传递给函数的参数:如果需要向线程函数传递参数,这些参数应该在创建线程时一并提供。

其他可选参数:一些可选参数可以通过第二个参数传递给std::thread构造函数,例如线程的启动参数等。

比如我下面这句话std::thread m_thOne = std::thread(&fun1);
创建一个名为m_thOne的线程,线程调用的是函数f1。这里第一个参数要传递函数的地址。

如果有一个函数void fun3(int a,string b);这个函数是类FUN的一个成员函数。

class FUN
{
public::void fun3(int a,string b){};
}

那么在main中我想开一个线程跑这个fun3函数,现有一个FUN的对象指针m_pfun,一个int类型参数a1,string类型参数b1。
在开线程的时候传参的写法如下:
std::thread(&fun3,m_pfun,a1,b1);

再结合一下上面的说明,第一个参数是函数的地址,第二个参数是谁调用这个函数,对应的这个调用函数的对象地址,第三个以及后面的参数是调用函数的参数。


2. 多线程释放

我们都知道,在使用new的方式创建新的对象,这个对象使用完之后如果不用delete进行释放,那么就会造成内存泄露。

我们创建线程之后,释放通常由 std::thread 的析构函数自动处理,但是关于这一点,存在一个注意点
那如果子线程在运行,但主线程已经跑完了,此时要关闭程序,就会调用析构,可是子线程还在运行,这就会出发异常。
正常的程序应该是,等所有的线程都运行完之后,要确保每个线程在主线程退出之前完成执行,就需要提及到函数join()

join() 用于阻塞当前线程,直到被调用的线程完成执行。调用 join() 后,当前线程会等待直到被 join() 的线程终止,然后继续执行。
确保在线程结束后主线程能够正确处理资源,防止线程终止时资源泄漏。

与之相类似的还有一个函数detach()

detach() 用于将线程与其主线程分离。分离后的线程在后台独立运行,主线程不再需要等待它完成。
子线程在分离后继续运行,即使主线程已经结束。分离线程的资源由系统自动管理。

归纳一下:
join()会阻塞线程,让主线程等join的子线程执行完再接着执行;(插队后排队)
detach()不会阻塞主线程,主线程执行结束也和子线程无关。(从原队中踢出后开新的一队)

所以要确保在线程结束后主线程能够正确处理资源,防止线程终止时资源泄漏,最好的方式其实使用join()函数。


3. 实例

接下来我们看一个实例。
这里我把刚才提到的FUN类放进例子中,通过一个FUN的一个指针m_pfun进行调用fun3函数,最后进行了释放。
这里delete是把指针指向的内存释放,但是指针还是指向那个内存,所以指针还要置空。

fun1和fun2函数和fun3基本类似,少了两个参数,也是延时输出。

我例子中都用了,下面这种方式来确保程序的正常结束。

if (m_thOne.joinable()){m_thOne.join();}

看明白下面的实例,多线程的就可以尝试写一写了。

#include <iostream>
#include <thread>
#include <chrono>class FUN
{
public:void fun3(int a, std::string b){std::cout << "fun3 start" << std::endl;std::chrono::seconds delay(7);std::this_thread::sleep_for(delay);std::cout << "fun3 end" << std::endl;};
};
void fun1()
{std::cout << "fun1 start" << std::endl;std::chrono::seconds delay(3);std::this_thread::sleep_for(delay);std::cout << "fun1 end" << std::endl;
}
void fun2()
{std::cout << "fun2 start" << std::endl;std::chrono::seconds delay(5);std::this_thread::sleep_for(delay);std::cout << "fun2 end" << std::endl;
}
int main()
{std::thread m_thOne = std::thread(&fun1);std::thread m_thTwo = std::thread(&fun2);FUN* m_pfun = new FUN();int a =1;std::string b = "b";std::thread m_thThree = std::thread(&FUN::fun3, m_pfun, a, b);std::cout << "Hello World!\n";if (m_thOne.joinable()){m_thOne.join();}if (m_thTwo.joinable()){m_thTwo.join();}if (m_thThree.joinable()){m_thThree.join();}delete m_pfun;m_pfun = nullptr;return 0;
}

在这里插入图片描述


总结

多线程还是很有用的,C++程序员进阶的必通之路。大学里面学的那些小玩意儿,单线程就能搞定所有,真正的大型项目,还是会有很多多线程相关的。
记住这个多线程demo的简单使用,那么后面进一步拓展就手到擒来了。

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

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

相关文章

[Qt][QSS][下]详细讲解

目录 1.样式属性0.前言1.盒模型(Box Model) 2.常用控件样式属性1.按钮2.复选框3.单选框4.输入框5.列表6.菜单栏7.注意 1.样式属性 0.前言 QSS中的样式属性⾮常多&#xff0c;不需要都记住&#xff0c;核⼼原则是⽤到了就去查 ⼤部分的属性和CSS是⾮常相似的 QSS中有些属性&am…

RK3588——网口实时传输视频

由于通过流媒体服务器传输画面延迟太高的问题&#xff0c;不知道是没有调试到合适的参数还是其他什么问题。诞生了这篇博客。 RK3588板端上接摄像头&#xff0c;采集画面&#xff0c;通过网口实时传输给上位机并显示。 第一代版本 RK3588代码 import cv2 import socket imp…

C++发送邮件:如何稳定实现邮件发送功能?

C发送邮件安全性探讨&#xff01;C编程中发送邮件的技巧&#xff1f; 邮件发送功能是许多应用程序的重要组成部分&#xff0c;无论是用于通知用户&#xff0c;还是用于自动化报告。AokSend将探讨如何在C环境中稳定地实现邮件发送功能&#xff0c;确保邮件能够可靠地到达收件人…

windows环境基于python 实现微信公众号文章推送

材料&#xff1a; 1、python 2.7 或者 python3.x 2、windows 可以通过 “python -m pip --version” 查看当前的pip 版本 E:\Downloads\newsInfo>python -m pip --version pip 20.3.4 from C:\Python27\lib\site-packages\pip (python 2.7) 3、windows 系统 制作&#xf…

云计算实训30——自动化运维(ansible)

自动化运维 ansible----自动化运维工具 特点&#xff1a; 部署简单&#xff0c;使用ssh管理 管理端与被管理端不需要启动服务 配置简单、功能强大&#xff0c;扩展性强 一、ansible环境搭建 准备四台机器 安装步骤 mo服务器&#xff1a; #下载epel [rootmo ~]# yum -y i…

windows主机查询url请求来自哪里发起的

最近使用fiddler抓包&#xff0c;看到一直有http://conna.gj.qq.com:47873 的请求&#xff0c; 对此进行溯源&#xff0c;确定是不是被攻击了。 在dos里查询端口进程&#xff1a;netstat -ano | findstr :47873 查到来自8020的进程id 查看此进程应用&#xff0c;发现竟然是…

C++ 设计模式——外观模式

外观模式 C 设计模式——外观模式主要组成部分1. 外观类&#xff08;Facade&#xff09;2. 子系统类&#xff08;Subsystem&#xff09;3. 客户端&#xff08;Client&#xff09; 例一&#xff1a;工作流程示例1. 外观类&#xff08;Facade&#xff09;2. 子系统类&#xff08;…

IT管理:我与IT的故事6--数字化建设规划工作坊圆满开展

在数字化浪潮席卷全球的时代背景下&#xff0c;企业的数字化转型已成为必然趋势。IT 部落精心打造的数字化规划实操工作坊顺利举办&#xff0c;为众多CIO的数字化转型之路点亮了明灯。 本次工作坊特别邀请到了业界知名的大咖讲师 Frank&#xff0c;他在数字化领域深耕多年&am…

最长的严格递增或递减子数组

给你一个整数数组 nums 。 返回数组 nums 中 严格递增 或 严格递减 的最长非空子数组的长度。 示例 1&#xff1a; 输入&#xff1a;nums [1,4,3,3,2] 输出&#xff1a;2 解释&#xff1a; nums 中严格递增的子数组有[1]、[2]、[3]、[3]、[4] 以及 [1,4] 。 nums 中…

【源码+文档+调试讲解】学院网站

摘 要 使用旧方法对冀中工程技师学院网站的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在冀中工程技师学院网站的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次…

Etcd:分布式键值存储的基石

Etcd 是一个分布式的、一致性的键值存储系统&#xff0c;由 CoreOS 设计并开源。它主要用于共享配置和服务发现&#xff0c;并且被广泛应用于 Kubernetes、Docker 和其他云原生工具中作为核心组件之一。Etcd 使用 Raft 一致性算法来保证数据的一致性&#xff0c;使得它非常适合…

MinerU 是一款将PDF转化如markdown、json工具

MinerU 项目简介 MinerU是一款将PDF转化为机器可读格式的工具&#xff08;如markdown、json&#xff09;&#xff0c;可以很方便地抽取为任意格式。 MinerU诞生于书生-浦语的预训练过程中&#xff0c;我们将会集中精力解决科技文献中的符号转化问题&#xff0c;希望在大模型时…

Day23 第十站 文件IO的多路复用

#include <myhead.h>void insert_client(int *client_arr,int *len,int client) {//client_arr[n]{3,4} len&client_count,client_count2;//添加 5 client_arr[2(*len)]5(client)client_arr[*len]client;(*len); } int find_client(int *client_arr,int len,int clie…

Rembg.js - 照片去背景AI开发包

Rembg.js适用于为人物、建筑、电商产品等各种照片自动去除背景&#xff0c;可直接在浏览器内运行&#xff0c; 提供前端JavaScirpt二次开发接口。官方下载地址&#xff1a;Rembg.js图片去背景开发包 。 1、目录组织 Rembg.js开发包的目录组织说明如下&#xff1a; rembg …

ECMAScript性能优化技巧与陷阱

1. 简介 1.1. 概述 ECMAScript是一种编程语言,它是JavaScript的核心语法。ECMAScript是由Ecma International组织定义的标准,它规定了JavaScript的基本语法和核心特性。ECMAScript的前身是JavaScript,但是随着JavaScript的发展,它已经逐渐脱离了JavaScript,成为了一种独…

RocketMQ源码分析 - 环境搭建

RocketMQ源码分析 - 环境搭建 环境搭建源码拉取导入IDEA调试1) 启动NameServer2) 启动Broker3) 发送消息4) 消费消息 环境搭建 依赖工具 JDK&#xff1a;1.8MavenIntellij IDEA 源码拉取 从官方仓库 https://github.com/apache/rocketmq clone或者download源码。 源码目录…

PCIe学习笔记(26)

Error Forwarding&#xff08;错误转发&#xff09; 错误转发(也称为数据中毒)&#xff0c;通过设置EP位表示。下面是一些使用错误转发的例子: •例#1:从主存读取遇到不可纠正的错误 •例#2:PCI写到主存的奇偶校验错误 •例#3:内部数据缓冲区或缓存上的数据完整性错误 错误…

【题目/训练】:双指针

引言 我们已经在这篇博客【算法/学习】双指针-CSDN博客里面讲了双指针、二分等的相关知识。 现在我们来做一些训练吧 经典例题 1. 移动零 思路&#xff1a; 使用 0 当做这个中间点&#xff0c;把不等于 0(注意题目没说不能有负数)的放到中间点的左边&#xff0c;等于 0 的…

在Ubuntu16.04里安装ROS Kinetic

1.设置apt的source list sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu$(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list 2.设置gpd keys sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365…

基于java的酒店管理系统设计与实现

系统分析与设计 需求分析 1.系统概要 根据餐饮系统的流程&#xff0c;完成从用户登录到开台点菜&#xff0c;到结账收银&#xff0c;到统计一条线的信息化管理&#xff0c;因此整个餐饮管理信息系统的研发内容就是开发一整套餐饮管理信息系统&#xff0c;实现餐饮业务的计算…