C++多线程编程(第二章 多线程通信和同步)

news2024/12/28 5:04:24

1、多线程状态

1.1线程状态说明

初始化(Init):该线程正在被创建;
就绪(Ready):该线程在就绪列表中,等待CPU调度;
运行(Running):该线程正在运行;
阻塞(Blocked):该线程被阻塞挂起,Blocked状态包括:pend(锁、事件、信号量等阻塞)、suspend(主动pend)、delay(延时阻塞)、pendtime(因为锁、事件、信号量时间等超时等待)
退出(Exit):该线程运行结束,等待父线程回收其控制块资源;
在这里插入图片描述

2、竞争状态(Race Condition)和临界区(Critical Section)

2.1、竞争状态

多线程同时读写共享数据

2.2、临界区

读写共享数据代码片段

避免竞争状态策略,对临界区进行保护,同时只能有一个线程进入临界区

3、互斥体和锁mutex

3.1互斥锁mutex

#include <thread>
#include <iostream>
#include <string>
#include <mutex>

using namespace std;
static mutex mux;//全局锁

void TestThread()
{
	//获取锁资源,如果没有锁则阻塞等待
	mux.lock();
	cout << "=======================================" << endl;
	cout << "test 001" << endl;
	cout << "test 002" << endl;
	cout << "test 003" << endl;
	cout << "=======================================" << endl;
	mux.unlock();
}

void TestThread2()
{//尝试获取锁
	//获取锁资源,如果没有锁则阻塞等待
	//mux.lock();
	for (;;)
	{
		if (!mux.try_lock())//有性能开销的,所以要等待一下
		{
			cout << "." << flush;
			this_thread::sleep_for(100ms);//等待一下再尝试

			continue;
		}
		cout << "=======================================" << endl;
		cout << "test 001" << endl;
		cout << "test 002" << endl;
		cout << "test 003" << endl;
		cout << "=======================================" << endl;
		mux.unlock();
		this_thread::sleep_for(3000ms);//等待一下,便于观察竞争的状态
	}
	
}
int main()
{
	printf("Demo1:\n");
	for (int i = 0; i < 2; i++)
	{
		thread th(TestThread);
		th.detach();
	}
	getchar();

	printf("Demo2:\n");
	for (int i = 0; i < 2; i++)
	{
		thread th(TestThread2);
		th.detach();
	}
	getchar();

	return 0;
}

3.2、互斥锁的坑_线程抢占不到资源的思考及解决方案

#include <thread>
#include <iostream>
#include <string>
#include <mutex>

using namespace std;
static mutex mux;//全局锁

void ThreadMainMux(int i)
{
	for (;;)//死循环
	{
		mux.lock();
		cout << i << "[in]" << endl;
		this_thread::sleep_for(1000ms);//模拟干活
		mux.unlock();
		this_thread::sleep_for(1ms);//这是系统获取锁的关键,解锁后等待一下,其他线程好获取到锁,这样就可以并发的所有线程都可以在执行
	}
}


int main()
{
	//并发三个守护线程
	for (int i = 0; i < 3; i++)
	{
		thread th(ThreadMainMux,i);
		th.detach();
	}
	getchar();
	return 0;
}

解锁后没有等待的情况如下
在这里插入图片描述
解锁后等待1毫秒,让其他线程可以获取到锁,运行结果如下
在这里插入图片描述

3.3、超时锁应用 time_mutex(避免长时间死锁)

可以记录锁获取情况,多次超时,可以记录日志,获取错误情况

//超时锁应用 timed_mutex(避免长时间死锁)


#include <thread>
#include <iostream>
#include <string>
#include <mutex>

using namespace std;
//static mutex mux;//全局锁
timed_mutex tmux;//超时锁
void ThreadMainTime(int i)
{
	for (;;)
	{
		//if (!tmux.try_lock_for(chrono::milliseconds(500)))//如果超时500毫秒,返回false
		if (!tmux.try_lock_for(500ms))//两种方式都可以
		{
			cout << i << "[try_lock_for timeout]" << endl;
			continue;
		}
		cout << i << "[in]" << endl;
		this_thread::sleep_for(2000ms);
		tmux.unlock();
		this_thread::sleep_for(1ms);
	}
}

int main()
{
	//并发三个守护线程
	for (int i = 0; i < 3; i++)
	{
		thread th(ThreadMainTime, i);
		th.detach();
	}
	getchar();
	return 0;
}

在这里插入图片描述

3.4、递归锁(可重入)recursive_mutex 和recursive_timed_mutex用于业务组合

同一个线程种同一把锁可以锁多次,避免了一些不必要的死锁;
组合业务,用到同一个锁

//可重入的锁,递归锁
#include <thread>
#include <iostream>
#include <string>
#include <mutex>

using namespace std;
//static mutex mux;//全局锁
//timed_mutex tmux;//超时锁

recursive_mutex rmux;//可重入的锁,

void Task1()
{//业务1
	rmux.lock();
	cout << "task1 [in]" << endl;
	rmux.unlock();
}
void Task2()
{//业务2
	rmux.lock();
	cout << "task2 [in]" << endl;
	rmux.unlock();
}

void ThreadMainRec(int i)
{
	for (;;)
	{
		rmux.lock();
		Task1();//这个任务中还用到了重入锁,普通锁是不能锁两次的,避免竞争
		cout << i << "[in]" << endl;
		this_thread::sleep_for(2000ms);
		Task2();//这个任务中还用到了重入锁,普通锁是不能锁两次的,避免竞争
		rmux.unlock();
		this_thread::sleep_for(1ms);

	}
}

int main()
{
	//并发三个守护线程
	for (int i = 0; i < 3; i++)
	{
		thread th(ThreadMainRec, i);
		th.detach();
	}
	getchar();
	return 0;
}

在这里插入图片描述

3.5、共享锁 shared_mutex

C++ 14共享超时互斥锁 shared_timed_mutex
C++ 17共享互斥锁 shareD_mutex
查看自己vs支持哪些C++版本,如下截图
在这里插入图片描述
共享锁中包含了共享锁和互斥锁,当互斥锁被锁定,所有共享锁都进不去;共享锁中的共享锁,只要在没有锁定共享锁中的互斥锁,共享锁中的共享锁都能进入;

//共享锁,读的时候所有线程都能读,写的时候读的线程不能读,只能写

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>

using namespace std;
//static mutex mux;//全局锁
//timed_mutex tmux;//超时锁
//recursive_mutex rmux;//可重入的锁,

//shared_mutex smux;//C++ 17支持
shared_timed_mutex stmux;//C++ 14支持



void ThreadRead(int i)
{//读的部分
	for (;;)
	{
		stmux.lock_shared();//只要没有把互斥锁锁住,共享锁都能进去
		this_thread::sleep_for(500ms);
		cout << i << "Read" << endl;
		stmux.unlock_shared();
		this_thread::sleep_for(1ms);
	}
}

void ThreadWrite(int i)
{//写的部分
	for (;;)
	{
		stmux.lock();//互斥锁锁住,共享锁都进不去
		this_thread::sleep_for(300ms);
		cout << i << "Write" << endl;
		stmux.unlock();
		this_thread::sleep_for(1ms);//防止资源无线使用
	}
}



int main()
{
	//并发三个守护线程
	for (int i = 0; i < 3; i++)
	{
		thread th(ThreadWrite, i);
		th.detach();
	}
	for (int i = 0; i < 3; i++)
	{
		thread th(ThreadRead, i);
		th.detach();
	}
	getchar();
	return 0;
}

在这里插入图片描述

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

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

相关文章

idea下tomcat运行乱码问题解决方法

idea虚拟机选项添加-Dfile.encodingUTF-8

yaml-cpp YAML格式处理库的介绍和使用(面向业务编程-文件格式处理)

YAML格式介绍 YAML的格式介绍&#xff0c;有关ini、json和xml或许很多人已经很了解了&#xff0c;但是关于YAML&#xff0c;还有许多人不了解。YAML被设计成更适合人类阅读&#xff08;我想正因为如此&#xff0c;所以相对来说更灵活&#xff0c;就导致到使用的时候很多人会觉…

PostMan+Jmeter+QTP工具介绍及安装

目录 一、PostMan介绍​编辑 二、下载安装 三、Postman与Jmeter的区别 一、开发语言区别&#xff1a; 二、使用范围区别&#xff1a; 三、使用区别&#xff1a; 四、Jmeter安装 附一个详细的Jmeter按照新手使用教程&#xff0c;感谢作者&#xff0c;亲测有效。 五、Jme…

python_day14_综合案例

文件内容 导包配置 import jsonfrom pyspark import SparkContext, SparkConf import osos.environ["PYSPARK_PYTHON"] "D:/dev/python/python3.10.4/python.exe" os.environ["HADOOP_HOME"] "D:/dev/hadoop-3.0.0" conf SparkC…

Megatron-LM、NVIDIA NeMo、model_optim_rng.pt 文件是什么?

本文涉及以下几个概念&#xff0c;分别是&#xff1a; Megatron和Megatron-LM-v1.1.5-3D_parallelism NVIDIA NeMo Megatron和Megatron-LM-v1.1.5-3D_parallelism是什么&#xff1f; Megatron是由NVIDIA开发的一种用于训练大规模语言模型的开源框架。它旨在提供高效的分布式…

鸿蒙4.0重大官宣!六大功能呼之欲出!

鸿蒙系统是当年华为为应对美国封杀而开发的操作系统,当时只是权宜之计&#xff0c;但没想到它的发展壮大远远超出了人们的预期,2021年其用户就突破了1亿,去年7月搭载鸿蒙系统的设备超过了3亿。近日,华为官宣将在今年8月4号的开发者大会上发布全新的鸿蒙4.0系统,系统包含多项让人…

THM-被动侦察和主动侦察

被动与主动侦察# 在计算机系统和网络出现之前&#xff0c;孙子兵法在孙子兵法中教导说&#xff1a;“知己知彼&#xff0c;必胜不疑。” 如果您扮演攻击者的角色&#xff0c;则需要收集有关目标系统的信息。如果你扮演防御者的角色&#xff0c;你需要知道你的对手会发现你的系…

加利福尼亚大学|3D-LLM:将3D世界于大规模语言模型结合

来自加利福尼亚大学的3D-LLM项目团队提到&#xff1a;大型语言模型 (LLM) 和视觉语言模型 (VLM) 已被证明在多项任务上表现出色&#xff0c;例如常识推理。尽管这些模型非常强大&#xff0c;但它们并不以 3D 物理世界为基础&#xff0c;而 3D 物理世界涉及更丰富的概念&#xf…

视频监控管理平台EasyCVR录像的3种方式

视频监控综合管理平台EasyCVR可以实现海量资源的接入、汇聚、计算、存储、处理等&#xff0c;平台具备轻量化接入能力&#xff0c;可支持多协议方式接入&#xff0c;包括主流标准协议GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Eho…

深入理解 python 虚拟机:字节码灵魂——Code obejct

Code Object 数据结构 typedef struct {PyObject_HEADint co_argcount; /* #arguments, except *args */int co_kwonlyargcount; /* #keyword only arguments */int co_nlocals; /* #local variables */int co_stacksize; /* #entries needed for evaluation stack */int co_f…

Flutter 异步编程指南作

1 Dart 中的事件循环模型 在 App 开发中&#xff0c;经常会遇到处理异步任务的场景&#xff0c;如网络请求、读写文件等。Android、iOS 使用的是多线程&#xff0c;而在 Flutter 中为单线程事件循环&#xff0c;如下图所示 Dart 中有两个任务队列&#xff0c;分别为 microtask…

Windows 11的最新人工智能应用Windows Copilot面世!

Windows Copilot是Windows 11预览版中的一项AI辅助功能。 Windows 11还包括设置应用程序的更改&#xff0c;更广泛的支持压缩文件格式。 上个月&#xff0c;微软宣布将继续其将ChatGPT应用于所有产品的冒险之旅&#xff0c;推出了名为Copilot的新Windows 11功能。几个月前&…

难评的Worldcoin,正在登月中

7月24日&#xff0c;前段时间搅混加密舆论界一汪春水的Worldcoin正式上线代币WLD。 由Openai创始人Sam Altman牵头的Worldcoin项目在其试点之初就备受关注&#xff0c;而该种关注在其融资近一亿美金后更是空前&#xff0c;币种上架的呼声不断。 但当代币真的狼来了时&#xff0…

使用CRM分析数据有哪些功能?

CRM数据分析软件可以帮助企业增强竞争力&#xff0c;并更好地了解客户需求及市场变化&#xff0c;助力企业数据分析&#xff0c;并提供实时更新的数据和分析结果&#xff0c;CRM数据分析软件的主要特点是什么&#xff1f;包括以下6个特点。 CRM数据分析软件的主要功能通常包括…

四、约束-2.演示

【案例】 根据需求&#xff0c;完成表结构的创建 创建一个user表&#xff1a; create table user(id int primary key auto_increment comment 主键,name varchar(10) not null unique comment 姓名,age int check ( age > 0 && age < 120 ) comment 年龄,statu…

《嵌入式系统工程师》精讲视频-希赛网--视频笔记

只看我不熟的内容 P8 04流水线 理论公式必须熟悉 P29 01OSI&#xff0f;RM 1年大概考4分&#xff0c;主要考察前3个知识点 应用层--与用户打交道&#xff1b;表示层--压缩、加密等&#xff1b;会话层--建立、终止会话&#xff1b; 传输层--建立端到端连接&#xff1b;网络层--路…

vue-cli-service requires Node ^12.0.0 || >= 14.0.0

运行npm run serve 时&#xff0c;报错如下&#xff1a; 系统&#xff1a;win7 node版本&#xff1a;13.14.0 解决方法&#xff1a; 根据路径&#xff08;node_modules/vue/cli-service/package.json&#xff09;找到package.json文件&#xff0c;并将engines的node属性值改为…

关于Ubuntu 18.04 LTS环境下运行程序出现的问题

关于Ubuntu 18.04 LTS环境下运行程序出现的问题 1.运行程序时出现以下情况 2.检查版本 strings /lib/x86_64-linux-gnu/libc.so.6 |grep GLIBC_​ 发现Ubuntu18.04下的glibc版本最高为2.27,而现程序所使用的是glibc2.34,所以没办法运行, 3.解决办法 安装glibc2.34库, …

C语言每日一题:7.寻找数组中心下标。

思路一&#xff1a; 暴力求解&#xff1a; 1.定义一个ps作为中间下标去记录下标值。 2.循环下标ps从头到位&#xff0c;定义四个变量分别是left sum_left,right,sum_right… 3.初始化leftps-1和rightps1.当ps0—>就让sum_left0,和psn-1->>>sum_right0; 4.循环结尾判…

深入探索文心千帆大模型平台:实现企业级大模型训练和推理

摘要&#xff1a;本文将介绍百度智能云推出的文心千帆大模型平台&#xff0c;以满足企业和个人客户的需求。通过该平台&#xff0c;用户可以进行大模型训练和推理&#xff0c;并且享受一站式的工具链和环境。作者将分享自己在平台上的亲身体验&#xff0c;并提供相关的代码示例…