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.mfbz.cn/a/871718.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

亲测解决Verifying shim SBAT data failed: Security Policy Violation

在小虎用u盘安装ubuntu系统的时候&#xff0c;笔记本出现了这个问题&#xff0c;解决方法是管关闭security boot。 解决方法 利用F2\F10\F12进入Bios设置&#xff0c;关闭security boot即可。 Use F2 to enter the bios security settings, close it. 参考 Verifying shim…

揭秘Semantic Kernel:用AI自动规划和执行用户请求

在我们日益高效的开发世界中&#xff0c;将任务自动化并智能规划变得越来越必要。今天&#xff0c;我要给大家介绍一个强大的概念——Semantic Kernel中的planner功能。通过这篇文章&#xff0c;我们会学习到planner的工作原理以及如何实现智能任务规划。 什么是planner&#x…

Spring GateWay自定义断言工厂

文章目录 概要整体架构流程最终的处理效果小结 概要 我们在线上系统部署了&#xff0c;灰度环境和生产环境时&#xff0c;可以通过自定义断言工厂去将请求需要路由到灰度环境的用户调用灰度的的服务集群&#xff0c;将正常的用户调用正常集群。 这样&#xff0c;我们可以在上线…

R语言论文插图模板第7期—分组散点图

在之前的文章中&#xff0c;分享过R语言折线图的绘制模板&#xff1a; 柱状图的绘制模板&#xff1a; 本期再来分享一下散点图&#xff08;分组&#xff09;的绘制方法。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;…

碰撞检测 | 基于ROS Rviz插件的多边形碰撞检测仿真平台

目录 0 专栏介绍1 基于多边形的碰撞检测2 碰撞检测仿真平台搭建2.1 多边形实例2.2 外部服务接口2.3 Rviz插件化 3 案例演示3.1 功能介绍3.2 绘制多边形 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及更高阶的运动规划算法轨迹优化实战…

【附源码】Python :PYQT界面点击按钮随机变色

系列文章目录 Python 界面学习&#xff1a;PYQT界面点击按钮随机变色 文章目录 系列文章目录一、项目需求二、源代码三、代码分析3.1 导入模块&#xff1a;3.2 定义App类&#xff1a;3.3 构造函数&#xff1a;3.4 初始化用户界面&#xff1a;3.5 设置窗口属性&#xff1a;3.6 …

基于距离度量学习的异常检测:一种通过相关距离度量的异常检测方法

异常通常被定义为数据集中与大多数其他项目非常不同的项目。或者说任何与所有其他记录(或几乎所有其他记录)显著不同的记录,并且与其他记录的差异程度超出正常范围,都可以合理地被认为是异常。 例如上图显示的数据集中,我们有四个簇(A、B、C和D)和三个位于这些簇之外的点:P1、P…

client网络模块的开发和client与server端的部分联动调试

客户端网络模块的开发 我们需要先了解socket通信的流程 socket通信 server端的流程 client端的流程 对于closesocket()函数来说 closesocket()是用来关闭套接字的,将套接字的描述符从内存清除,并不是删除了那个套接字,只是切断了联系,所以我们如果重复调用,不closesocket()…

Agentic Security:一款针对LLM模型的模糊测试与安全检测工具

关于Agentic Security Agentic Security是一款针对LLM模型的模糊测试与安全检测工具&#xff0c;该工具可以帮助广大研究人员针对任意LLM执行全面的安全分析与测试。 请注意 Agentic Security 是作为安全扫描工具设计的&#xff0c;而不是万无一失的解决方案。它无法保证完全防…

C++(11)类语法分析(2)

C(10)之类语法分析(2) Author: Once Day Date: 2024年8月17日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 源码分析_Once-Day的博客-CSDN博客 …

Python数据结构:集合详解(创建、集合操作)④

文章目录 1. Python集合概述2. 创建集合2.1 使用花括号 {} 创建集合2.2 使用 set() 函数创建集合2.3 创建空集合 3. 集合操作3.1 添加和删除元素3.2 集合的基本操作3.3 集合的比较操作3.4 不可变集合&#xff08;frozenset&#xff09; 4. 综合例子&#xff1a;图书管理系统 Py…

30秒内批量删除git本地分支

在开发过程中&#xff0c;我们经常需要对本地的 Git 分支进行管理。有时&#xff0c;由于各种原因&#xff0c;我们可能需要批量删除本地的分支。这可能是因为某些分支已经不再需要&#xff0c;或者是为了清理本地的分支列表&#xff0c;以保持整洁和易于管理。 要批量删除本地…

没有用的小技巧之---接入网线,有内网没有外网,但是可以登录微信

打开控制面板&#xff0c;找到网络和Internet 选择Internet选项 点击连接&#xff0c;选择局域网设置 取消勾选代理服务器

开放式耳机会打扰到别人吗?四款漏音处理做的好的蓝牙耳机

一般情况下&#xff0c;开放式耳机不会打扰到别人。 开放式耳机通常采用全开放设计&#xff0c;声音不会完全封闭在耳朵里&#xff0c;而是向四周扩散&#xff0c;相比封闭式耳机&#xff0c;其对外界环境的噪音影响更小 。而且现在的开放式耳机在技术上已经有了很大的进步&am…

[数据集][目标检测]工程机械车辆检测数据集VOC+YOLO格式3189张10类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3189 标注数量(xml文件个数)&#xff1a;3189 标注数量(txt文件个数)&#xff1a;3189 标注…

springboot的自动配置和怎么做自动配置

目录 一、Condition 1、Condition的具体实现 2、Condition小结 &#xff08;1&#xff09;自定义条件 &#xff08;2&#xff09;SpringBoot 提供的常用条件注解 二、Enable注解 三、EnableAutoConfiguration 注解和自动配置 1、EnableAutoConfiguration的三个注解属性…

git 学习--GitHub Gitee码云 GitLab

1 集中式和分布式的区别 1.1 集中式 集中式VCS必须有一台电脑作为服务器&#xff0c;每台电脑都把代码提交到服务器上&#xff0c;再从服务器下载代码。如果网络出现问题或服务器宕机&#xff0c;系统就不能使用了。 1.2 分布式 分布式VCS没有中央服务器&#xff0c;每台电脑…

Python编码系列—Python SQL与NoSQL数据库交互:深入探索与实战应用

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

预警先行,弯道哨兵让行车更安全

预警先行&#xff0c;弯道哨兵让行车更安全”这句话深刻体现了现代交通安全理念中预防为主、科技赋能的重要性。在道路交通中&#xff0c;尤其是复杂多变的弯道区域&#xff0c;交通事故的发生率往往较高&#xff0c;因此&#xff0c;采取有效的预警措施和引入先进的交通辅助设…

怎么管控终端电脑上的移动端口

管控终端电脑上的移动端口&#xff0c;尤其是USB等移动端口&#xff0c;是确保企业数据安全和提升网络管理效率的重要手段。 一、使用注册表编辑器禁用USB端口&#xff08;适用于Windows系统&#xff09; 打开注册表编辑器&#xff1a; 同时按下“WinR”组合键&#xff0c;打…