C++ 多线程学习总结

news2024/9/23 5:27:50

C++ 多线程

创建线程 thread

jion与detach方式的区别

  • jion方式:必须等待创建并启动的子线程任务执行完毕,才会继续往下执行。
    示例:
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <thread>

using namespace std;

void my_func1_task()
{
	cout << "I am my_func1_task" << endl;
	cout << "my_func1_task end" << endl;
}

void my_func2_task(int x)
{
	cout << "I am my_func2_task" << endl;
	while (x--)
	{
		cout << "x:" << x << ";";
		sleep(1);
	}
	cout << endl;
	cout << "my_func2_task end" << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread_1.join();
	
	thread thread_2(my_func2_task, 10);
	thread_2.join();
	cout << "thread end" << endl;

	cout << "main end" << endl;
	return 0;
}

测试结果:
在这里插入图片描述

  • detach方式:启动的子线程自主在后台运行,当前主线程代码继续往下执行,无需等待子线程结束。
    示例:
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <thread>

using namespace std;

void my_func1_task()
{
	cout << "I am my_func1_task" << endl;
	cout << "my_func1_task end" << endl;
}

void my_func2_task(int x)
{
	cout << "I am my_func2_task" << endl;
	while (x--)
	{
		cout << "x:" << x << ";";
		sleep(1);
	}
	cout << endl;
	cout << "my_func2_task end" << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread_1.detach();
	
	thread thread_2(my_func2_task, 10);
	thread_2.detach();
	cout << "thread end" << endl;

	cout << "main end" << endl;
	return 0;
}

测试结果:
在这里插入图片描述

线程锁 mutex

lock和unlock

不上锁测试示例:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <thread>

using namespace std;

int g_count = 10;

void my_func1_task()
{
	while (g_count-- > 0)
	{
		cout << "===func1===";
		sleep(1);
	}
	cout << endl;
}

void my_func2_task()
{
	while (g_count-- > 0)
	{
		cout << "***func2***";
		sleep(1);
	}
	cout << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread thread_2(my_func2_task);
	
	thread_1.join();
	thread_2.join();

	return 0;
}

测试结果:
在这里插入图片描述
上锁测试示例:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <thread>
#include <mutex>

using namespace std;

int g_count = 10;
mutex g_countMtx;

void my_func1_task()
{
	g_countMtx.lock();
	while (g_count-- > 0)
	{
		cout << "===func1===";
		sleep(1);
	}
	cout << endl;
	g_countMtx.unlock();
}

void my_func2_task()
{
	g_countMtx.lock(); 
	while (g_count-- > 0)
	{
		cout << "***func2***";
		sleep(1);
	}
	cout << endl;
	g_countMtx.unlock();
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread thread_2(my_func2_task);
	
	thread_1.join();
	thread_2.join();

	return 0;
}

测试结果:
在这里插入图片描述

lock_guard

  • 作用:放在在lock后,忘记unlock。
  • 使用:在创建lock_guard对象时,将尝试获取提供给它的互斥锁的所有权。当控制流离开lock_guard对象的作用域时,lock_guard析构并释放互斥锁。
  • 特点:创建即加锁,作用域结束自动析构并解锁;不能中途解锁,必须等作用域结束才能解锁。
  • 使用技巧:可以根据需要通过使用{}增加临时作用域。
    测试示例:
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <thread>
#include <mutex>

using namespace std;

int g_count = 10;
mutex g_countMtx;

void my_func1_task()
{
	lock_guard<mutex> guard(g_countMtx);
	while (g_count-- > 0)
	{
		cout << "===func1===";
		sleep(1);
	}
	cout << endl;
}

void my_func2_task()
{
	lock_guard<mutex> guard(g_countMtx); 
	while (g_count-- > 0)
	{	
		cout << "***func2***";
		sleep(1);
	}
	cout << endl;
}

int main(int argc, char *argv[])
{
	cout << "this is main()" << endl;
	thread thread_1(my_func1_task);
	thread thread_2(my_func2_task);
	
	thread_1.join();
	thread_2.join();

	return 0;
}

测试结果:
在这里插入图片描述

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

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

相关文章

【企业架构实践】要避免的 7 个企业架构错误

颠覆性时代需要有弹性、前瞻性的企业架构。不要让错误的框架破坏您的组织实现当前和未来目标的能力。 企业架构为成功的业务 IT 计划奠定了基础。如果设计和实施得当&#xff0c;企业架构将帮助业务领导者实现他们的目标&#xff0c;使组织变得更具响应性、效率和竞争力。 不幸…

matlab使用教程(2)—数组索引、工作区与字符

1数组索引 MATLAB 中的每个变量都是一个可包含许多数字的数组。如果要访问数组的选定元素&#xff0c;请使用索引。 例如&#xff0c;假设有 44 矩阵 A &#xff1a; A [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16] A 44 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 引…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接&#xff0c;进入国务院政策文件库&#xff0c;分为国务院文件和部门文件&#xff08;发改委、工信部、交通运输部、市场监督局、商务部等&#xff…

JavaScript 中 五种迭代数组的方法 every some map filter forEach

JavaScript 中 五种迭代数组的方法 every some map filter forEach 1.every 和 some2.filter (重点常用)3.map (灵活常用&#xff09;4.forEach (重点常用) ECMAScript 提供了 5个对数组的迭代方法 1.every() 2.some() 3.filter() 4.forEach() 5.map() 1.every 和 some every…

串联型PI和并联型PI调节器的比较

一、PI调节器的种类 图3-4 仿真波形变化情况&#xff08;串联型PI调节器&#xff0c;1500r/min&#xff09; 从图3-1到3-4比较可知&#xff0c;与并联型PI调节器相比&#xff0c;串联型PI调节器的超调量很小&#xff08;速度环&#xff09;&#xff0c;且动态过程时间短&…

从新的角度看待大模型微调

一、前言 一切要从最近大火的Lora(《LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS》&#xff09;说起&#xff0c;该文章在ICLR2022中提出。说的是利用低秩适配(low-rank adaptation)的方法&#xff0c;可以在使用大模型适配下游任务时只需要训练少量的参数即可达到一…

【SQL应知应会】表分区(二)• MySQL版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 分区表 • MySQL版 前言一、分区表1.非分区表2.分区…

【运维】第03讲(下):Nginx 负载均衡常见架构及问题解析

Nginx 负载均衡常见问题 那么,Nginx 负载均衡的通常配置会出现哪些问题呢?这里列出几种比较常见的问题: 客户端 IP 地址获取问题域名携带问题负载均衡导致 session 丢失问题动态负载均衡问题真实的 Realserver 状态检测接下来,我们就重点讲解下 Nginx 作为负载均衡的这几个…

从代码角度戳一下springMVC的运行过程-spring16

1、首先页面需要输入地址&#xff1a; 2、画张图------ 这个地址先找Tomcat,而Tomcat帮你找你的工程 3、 4、每次都要过这个地方 这句servlet代码 具体流程是&#xff1a; SpringMVC的执行流程 这个Handler干嘛&#xff1f;负责对你的请求进行解析&#xff0c;知道我最终要找…

WAIC2023丨AI图像内容安全“黑科技”如何助力科技发展?

〇、前言 7月7日下午&#xff0c;2023世界人工智能大会&#xff08;WAIC&#xff09;“聚焦大模型时代AIGC新浪潮—可信AI”论坛在上海世博中心红厅举行。人工智能等技术前沿领域的著名专家与学者、投资人和领军创业者汇聚一堂&#xff0c;共同探索中国科技创新的驱动力量。 在…

latex3【排版】

多行公式排版&#xff1a;&#xff08;gather、align、split、cases&#xff09; \section{多行公式}%gather环境\begin{gather} abba \\ abcbaccbacab\end{gather}\begin{gather*} abba \\ abcbaccbacab\end{gather*}​\begin{gather} abba \\ 123 \notag …

贪吃蛇游戏制作

目录 前言 游戏设计 游戏三部曲 函数说明 优化设计 1 前言 终极目标&#xff1a;打造酷炫贪吃蛇游戏 制作环境: VS2015(支持VC2010,VS各个版本) easyx图形库(稍微改下VC6.0也可以实现) 2 游戏设计 贪吃蛇的制作思路就是蛇头带动蛇尾移动&#xff0c;主要…

记一次linux服务器k8s服务失败,重新安装centos系统并部署k8s以及服务【2023年7月15日】

周五&#xff0c;突然收到微信消息说&#xff1a;兄嘚~ 网站无法访问了&#xff01; 我以为就是普通的小问题&#xff0c;连上服务器看报错呢&#xff0c;执行kubectl get nodes [rootnode101 ~]# kubectl get nodes The connection to the server 127.0.0.1:6443 was refused…

FL Studio 21具有哪些功能?flstudio21会有什么新功能

FL Studio 21 是一个功能完备的音乐制作环境&#xff0c;能够进行多轨道音频录制、音序处理和混音&#xff0c;可以帮助用户创作专业质量的音乐轨道。 借助 VST 托管、灵活的混音器、高级 MIDI 和 ReWire 支持&#xff0c;您将轻松驾驭各种音乐风格。 歌曲或循环可以导出为 .wa…

[QT编程系列-15]: 基础框架 - 信号与槽,connect函数详解

目录 一、线程内不同对象的通信 1.1 connect函数介绍 1.2 connect的用法 1.3 代码示例 二、不同线程间不同对象的通信 2.1 概述 2.2 代码案例 一、线程内不同对象的通信 1.1 connect函数介绍 在使用 Qt 框架进行开发时&#xff0c;connect 函数是用于建立信号与槽机…

hadoop -- Hbase

HBase是一个分布式、可扩展、面向列的数据存储&#xff08;百万级别列&#xff09;、可伸缩、高可靠性、实时读写的NoSQL 数据库。 HBase利用 Hadoop的 HDFS作为其文件存储系统&#xff0c; 利用MapReduce 来处理HBase中的海量数据&#xff0c; 利用Zookeeper作为分布式协同服…

AIGC之文本内容生成概述(下)——Transformer

在上一篇文章中&#xff0c;我们一口气介绍了LSTM、Word2Vec、GloVe、ELMo等四种模型的技术发展&#xff0c;以及每种模型的优缺点与应用场景&#xff0c;全文超过一万字&#xff0c;显得冗长且繁杂&#xff0c;在下文部分我们将分开介绍Transformer、BERT、GPT1/GPT2/GPT3/Cha…

electron+vue3全家桶+vite项目搭建【23】url唤醒应用,并传递参数

文章目录 引入实现效果实现步骤测试代码 引入 demo项目地址 很多场景下我们都希望通过url快速唤醒应用&#xff0c;例如百度网盘&#xff0c;在网页中唤醒应用&#xff0c;并传递下载链接&#xff0c;在electron中要实现这样的效果&#xff0c;就需要针对不同的平台做对应的处…

SpringMVC【SpringMVC拦截器、 SpringMVC跨域请求、SSM整合】(七)-全面详解(学习总结---从入门到深化)

目录 SpringMVC拦截器_拦截器过滤敏感词案例 SpringMVC跨域请求_同源策略 SpringMVC跨域请求_跨域请求 SpringMVC跨域请求_控制器接收跨域请求 SSM整合_需求分析 SSM整合_创建父工程 SSM整合_创建dao子工程 SSM整合_创建service子工程 SSM整合_创建controller子工程 …

Gradle和Aritifactory,实现上传Apk并发送消息到钉钉

Gradle和Aritifactory 本文链接&#xff1a;https://blog.csdn.net/feather_wch/article/details/131746580 文章目录 Gradle和AritifactoryGradle基本介绍Gradle插件开发流程本地仓库artifactory搭建添加仓库使用本地仓库gradle插件仓库引入 插件buildSrc开发步骤xxxPluginPg…