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

news2024/11/14 18:57:22

文章目录

  • 前言
  • 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.coloradmin.cn/o/2048436.html

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

相关文章

【Docker系列】Docker 容器时区设置指南

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

中国式现代化产业水平数据集(2011-2021年)

中国式现代化是一种社会主义现代化模式&#xff0c;它具有自己独特的特征和发展路径。这一现代化模式以实现国家富强、民族振兴和人民幸福为目标&#xff0c;强调物质文明与精神文明的协调发展以及人与自然的和谐共生 本文将中国式现代化理念与现代化产业体系相结合&#xff0…

希亦、洁盟、苏泊尔眼镜清洗机哪款好用?热门眼镜清洗机测评总结

随着科学技术的发展&#xff0c;电子设备的升级&#xff0c;越来越多的人开始戴眼镜&#xff0c;而眼镜由于长时间的佩戴&#xff0c;镜框以及镜面都积累了一些灰尘以及人们肉眼所看不见的细菌&#xff0c;但是如果你使用普通的清洁方式去清洗的话肯定是清洗不干净的&#xff0…

记录|Label组件如何控制下边框为直线

目录 前言一、问题描述二、重绘三、效果展示更新时间 前言 参考文章&#xff1a; C# WinForm开发时&#xff0c;仅显示label的下边框怎么解决啊&#xff1f; 验证过&#xff0c;方法可靠。并增加控制绘制的直线粗细的功能。 一、问题描述 C# winform中想只给Label组件的下边框…

佳能FAX-L160G打印机驱动程序安装

佳能FAX-L160G打印机驱动程序安装笔记 1.访问佳能官方网站https://www.canon.com.cn或者相关驱动下载网站&#xff0c;搜索并下载适用于佳能FAX-L160G打印机的驱动程序。 在这里跳出来相关系列&#xff08;没有精确的型号&#xff09;&#xff0c;点进去搜索。 选择第一个驱动…

强化进度慢,武忠祥17堂课怎么听最高效?

武忠祥老师的17堂课怎么看&#xff1f; 我的建议是&#xff0c;别乱看&#xff01; 17讲内容包括15个主要专题和2个附加专题&#xff0c;整体课时量还是相当大的。 以2023版的课时长度为例&#xff0c;即使你全程以1.5倍速观看且不做任何停顿&#xff0c;平均每个专题至少也…

系统项目管理师----高级----前情调研

要成功通过信息系统项目管理师的考试&#xff0c;需要系统性的学习和多方面的准备。以下是详细的学习资源、推荐的书籍和具体的备考步骤。 一、学习资源与网站 1. 官方网站与指南 中国计算机技术职业资格网&#xff1a;这是软考的官方网站&#xff0c;提供考试大纲、政策法规…

Java编程 : 对象的本质

1.1 从机器视角到问题视角的演变 在计算机科学的发展历程中&#xff0c;我们见证了从机器视角到问题视角的深刻转变。这一转变不仅体现了编程语言和技术的进步&#xff0c;更反映了我们对问题解决方式理解的深化。 起初&#xff0c;计算机编程主要依赖于机器视角。汇编语言作…

FPGA串口调试中当电脑串口无法正常通信,设备管理器中“其它设备”位置显示“USB-Blaster”显示感叹号等问题应该怎么解决?

一、问题描述 当我们进行FPGA开发关于串口等试验的设计中&#xff0c;都需要用到串口&#xff0c;而要使用串口就需要先安装串口驱动&#xff0c;但是在安装驱动的过程中会出现各种各样的问题。 这里就出现了如图所示的停产问题&#xff1a; 在图片中我们可以看到FPGA要使…

【promise】Promise的几个关键问题 (三)

Ⅰ-如何改变 promise 的状态? (1) resolve(value): 如果当前是 pending 就会变为 resolved (2) reject(reason): 如果当前是 pending 就会变为 rejected (3) 抛出异常: 如果当前是 pending 就会变为 rejected Ⅱ-一个 promise 指定多个成功/失败回调函数, 都会调用吗? 当 pro…

Jenkins-拉取代码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Jenkins环境配置&#xff08;一&#xff09;配置Maven环境&#xff08;1&#xff09;Maven下载&#xff08;2&#xff09;将Maven上传服务器&#xff08;3&…

解决Win11点击睡眠后,唤醒系统,程序全部关闭的问题

网上只是给出修改“在此时间后关闭硬盘”的时间&#xff0c;结果点击【睡眠】&#xff0c;重新唤醒系统&#xff0c;程序依旧全部关闭。这是因为点击【睡眠】时&#xff0c;启动了【休眠】&#xff0c;Win11系统中&#xff0c;休眠再唤醒系统&#xff0c;会导致程序全部关闭。我…

如何在 3 分钟内免费在 AWS 上运行 RStudio

欢迎来到雲闪世界。谈到数据分析&#xff0c;我有理由从本地计算机迁移到云端。最突出的是&#xff0c;您可以运行无限数量的机器&#xff0c;而无需拥有或维护它们。此外&#xff0c;您可以在几分钟内根据需要扩大或缩小规模。如果您选择运行 t2.micro 服务器&#xff0c;您可…

ant design pro 如何去保存颜色

上图 就是实现这样的效果 后端是这样的&#xff0c;这个颜色肯定是存到字符串里的 这是第一步 import mongoose, { Schema, Document } from mongoose;interface IDiscountCard extends Document {title: string;subtitle: string;image: string;shopUrl: string;bgColor: s…

望繁信科技荣膺上海市浦东新区博士后创新实践基地称号

近日&#xff0c;上海望繁信科技有限公司&#xff08;简称“望繁信科技”&#xff09;凭借在大数据流程智能领域的卓越表现&#xff0c;成功入选上海市浦东新区博士后创新实践基地。这一荣誉不仅是对望繁信科技创新能力和技术实力的高度认可&#xff0c;也标志着公司在推动产学…

基于springboot养老院管理系统pf

TOC springboot332基于springboot养老院管理系统pf 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔记…

Hive3:简单ETL实操案例

一、ETL概念简介 ETL&#xff1a; E&#xff0c;Extract&#xff0c;抽取 T&#xff0c;Transform&#xff0c;转换 L&#xff0c;Load&#xff0c;加载 从A抽取数据(E)&#xff0c;进行数据转换过滤(T)&#xff0c;将结果加载到B(L)&#xff0c;就是ETL 二、情景描述 聊天平…

数据结构(邓俊辉)学习笔记】优先级队列 04——完全二叉堆:插入与上滤

文章目录 1. 上滤2. 实例3. 实现4. 效率 1. 上滤 好&#xff0c;接下来我们就来学习在一个完全二叉堆中&#xff0c;如何有效地插入一个新的元素。我们将会看到插入过程中的核心技巧是所谓的 ”上滤“ 过程。 为了在完全二叉堆中引入一个新的词条 e&#xff0c;我们只需在物…

【网络编程】TCP实现网络通信(C语言、Ubuntu实现)

TCP服务器通信模型&#xff1a;&#xff08;分为以下6个步骤&#xff09; 1、sfd socket(); //创建一个用于连接的套接字文件描述符 2、bind(); //为服务器套接字绑定ip地址和端口号&#xff0c;为了让客户端额能够找到服务器 3、l…

C++第三十七弹---深入理解红黑树:旋转、着色与性质维护

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1 红黑树 1.1 红黑树的概念 1.2 红黑树的性质 1.3 红黑树节点的定义 1.4 红黑树结构 1.5 红黑树的插入操作 1.6 红黑树的验证 1.7 红黑树与…