c++介绍锁二

锁主要在两个以上的线程中使用,当多个线程访问共享资源时,我们需要使用锁,开保证共享资源的唯一性。

当两个线程访问不带锁的共享资源时,如下代码

#include<array>
#include<thread>
#include<iostream>
using namespace std;

void inc(int& res)
{
	for (int i = 0; i < 1000000; i++)
		res++;
}
int main1()
{
	int counter = 0;
	thread th1(inc,ref(counter));
	thread th2(inc, ref(counter));
	th1.join();
	th2.join();
	cout << "counter =" << counter << "\n";
	return 0;
}

得到结果

显然结果是不正确的。

这时我们需要加锁来限制 

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;


class Counter {
public:
	void inc()
	{
		counter_mutex.lock();
		m_count++;
		counter_mutex.unlock();
	}
	int getCounter()    //如果在多线程调用也需要加锁  这里没在多线程调用也加了锁
	{
		int temp;
		counter_mutex.lock();
		temp = m_count;
		counter_mutex.unlock();
		return temp;
	}
private:
	mutex counter_mutex;
	int m_count = 0;
};
int main2()
{
	Counter counter;
	auto increase = [](Counter& counter)
	{
		for (int i = 0; i < 1000000; i++)
			counter.inc();
	};
	thread th1(increase, ref(counter));
	thread th2(increase,ref(counter));
	th1.join();
	th2.join();
cout << "counter=" << counter.getCounter()<<"\n";
return 0;
}

由于上述加锁,代码的健壮性不是很好,如果遇到异常抛出情况,可能存在互斥量未释放问题。所以进一步改进

如下代码

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;


class Counter {
public:
	void inc()
	{
		lock_guard<mutex> lock(counter_mutex);
		m_count++;
	}
	int getCounter()
	{
		int temp;
		lock_guard<mutex> lock(counter_mutex);
		temp = m_count;
		return temp;
	}
private:
	mutex counter_mutex;
	int m_count = 0;
};
int main2()
{
	Counter counter;
	auto increase = [](Counter& counter)
	{
		for (int i = 0; i < 1000000; i++)
			counter.inc();
	};
	thread th1(increase, ref(counter));
	thread th2(increase,ref(counter));
	th1.join();
	th2.join();
cout << "counter=" << counter.getCounter()<<"\n";
return 0;
}

这样只要不在作用域范围内,锁就会释放,可以避免上述问题。

unique_lock更加灵活,可以创建后不锁定,在使用过程中进行锁定。

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;

class Counter
{
public:

	void increase(int n)
	{
		unique_lock<mutex>lock(counter_mutex,defer_lock);//延迟获取锁
		while (n--)
		{
			lock.lock();
			m_count++;
			lock.unlock();
		}
	}
	int getCount()
	{
		unique_lock<mutex> lock(counter_mutex);
		return m_count;
	}
private:
	mutex counter_mutex;
	int m_count = 0;
};
void main3()
{
	Counter counter;
	auto increase = [](Counter& counter) {
		counter.increase(1000000);
	};
	thread th1(increase, ref(counter));
	thread th2(increase, ref(counter));

	th1.join();
	th2.join();
	cout << "counter=" << counter.getCount() << "\n";

}

还有一种计时锁,设定在多少时间内进行锁定

#include<array>
#include<thread>
#include<iostream>
#include<mutex>
using namespace std;
//time_mutex

using namespace std::chrono_literals;
class TryDemo
{
public:
	void print()
	{
		for (int i =0; i < 10; i++)
		{
			unique_lock<timed_mutex>lock(m_mutex,defer_lock);

			if (lock.try_lock_for(100ms))//100ms是否获得该锁
			{
				{
					lock_guard<mutex> guard(count_mutex);
					cout << "[" << this_thread::get_id << "]" << "成功;\n";
				}
				this_thread::sleep_for(100ms);
			}
			else
			{
				lock_guard<mutex> lock_guard(count_mutex);
				cout << "[" << this_thread::get_id() << "]" << "失败;\n";
				this_thread::sleep_for(100ms);
			}
		}
	}
private:
	timed_mutex m_mutex;
	mutex count_mutex;
	int m_count = 0;
};
void main5()
{
	TryDemo demo;
	auto print = [](TryDemo& demo)
	{
		demo.print();
	};
		thread th1(print,ref(demo));
		thread th2(print, ref(demo));
		th1.join();
		th2.join();
}

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

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

相关文章

Ubuntu系统部署.NET 8网站项目

一、使用XShell连接 Ubuntu系统初次连接时默认的用户名为&#xff1a;ubuntu&#xff0c;使用此用户名与系统登录密码进行连接。 登录成功效果如下图&#xff1a; 二、root用户登录 linux下有超级用户&#xff08;root&#xff09;和普通用户&#xff0c;普通用户不能直接操…

学习资料电子版 免费下载的网盘网站(非常全!)

我分享一个私人收藏的电子书免费下载的网盘网站&#xff08;学习资料为主&#xff09;&#xff1a; link3.cc/sbook123 所有资料都保存在网盘了&#xff0c;直接转存即可&#xff0c;非常的便利&#xff01; 包括了少儿&#xff0c;小学&#xff0c;初中&#xff0c;中职&am…

图形编辑器基于Paper.js教程24:图像转gcode的重构,元素翻转,旋转

前段时间在雕刻图片时&#xff0c;旋转图片&#xff0c;翻转图片后&#xff0c;发现生成准确的gcode&#xff0c;虽然尺寸对&#xff0c;但是都是以没有旋转&#xff0c;没有翻转的图片进行生成的。后来思考了一下&#xff0c;发现这真是一个大bug&#xff0c;无论图片如何选择…

无公网IP也能远程控制Windows:Linux rdesktop内网穿透实战

文章目录 前言1. Windows 开启远程桌面2. Linux安装rdesktop工具3. Win安装Cpolar工具4. 配置远程桌面地址5. 远程桌面连接测试6. 设置固定远程地址7. 固定地址连接测试 前言 如今远程办公已经从一种选择变成了许多企业和个人的必修课&#xff0c;而如何在Linux系统上高效地访…

一文了解汽车图像传感器

2024年底,安森美做了题为"How Automotive Image Sensors Transform the Future of Autonomous Driving"的演讲,这里结合其内容对自动驾驶图像传感器做一个介绍。 当前的自动驾驶感知技术主要有两大技术路线:一种是仅使用摄像头作为传感器进行信息采集的纯…

Talking Head Review (数字人算法综述)

文章目录 引言3D Model basedGeneFace背景方案实验 GeneFace背景方案实现细节实验 Real3D-Portrait背景方案实现细节实验 MimicTalk背景方案实现细节实验 face-vid2vid背景方案实现细节实验 MegaPortraits背景方案实现细节实验 VASA-1背景方案实现细节实验 LivePortrait背景方案…

DeepSeekR1之四_在RAGFlow中配置DeepSeekR1模型

DeepSeekR1之四_在RAGFlow中配置DeepSeekR1模型 文章目录 DeepSeekR1之四_在RAGFlow中配置DeepSeekR1模型1. 通过Ollama下载模型1. 下载DeepSeekR1模型2. 下载嵌入模型 2. 查看本地的Ollama模型3. 模型提供商中添加模型1. 打开模型提供商2. 选择Ollama待添加模型3. 添加DeepSee…

【 <一> 炼丹初探:JavaWeb 的起源与基础】之 JavaWeb 项目的部署:从开发环境到生产环境

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、开发环境…

可视化图解算法:反转链表

1. 题目 描述 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据范围&#xff1a; 0<≤n≤1000 要求&#xff1a;空间复杂度 O(1) &#xf…

P8685 [蓝桥杯 2019 省 A] 外卖店优先级--优先队列“数组”!!!!!

P8685 [蓝桥杯 2019 省 A] 外卖店优先级 题目 解析优先队列如何判断是否使用优先队列&#xff1f;省略规则优先队列常用操作大顶堆 vs 小顶堆定义队列h队列数组 代码 题目 解析 每个外卖店会在不同的时间点收到订单&#xff0c;我们可以看见测试用例的时间顺序是不同的&#x…

使用苹果M芯片打包Docker Image无法在amd64环境下运行

问题所在 使用苹果M芯片打包Docker Image无法在amd64环境下运行&#xff0c;因为arm环境下打包docker默认打包为arm格式&#xff0c;可以使用以下命令查看&#xff1a; docker inspect <ImageID>找到Architecture&#xff0c;可以发现 解决方法 在docker-compose.ym…

低代码开发直聘管理系统

低代码 DeepSeek 组合的方式开发直聘管理系统&#xff0c;兼职是开挂的存在。整个管理后台系统 小程序端接口的输出&#xff0c;只花了两个星期不到。 一、技术栈 后端&#xff1a;SpringBoot mybatis MySQL Redis 前端&#xff1a;Vue elementui 二、整体效果 三、表结…

MySQL的安装及配置

一.以安装包方式下载 1.进入MySQL官网&#xff0c;下载安装包 官网链接&#xff1a;https://downloads.mysql.com/archives/installer/ 2.安装MySQL 二.压缩包方式下载 下载位置&#xff1a;mysql下载位置 解压缩后位置&#xff1a;D:\mysql-8.0.15-winx64 在主目录下复制…

CI/CD—Jenkins配置一次完整的jar自动化发布流程

背景&#xff1a; 实现设想&#xff1a; 要创建自动化发布&#xff0c;需要准备一台测试服务器提前安装好java运行所需的环境&#xff0c;JDK版本最好和Windows开发机器上的版本一致&#xff0c;在Jenkins上配置将构建好的jar上传到测试服务器上&#xff0c;测试服务器自动启动…

C++蓝桥杯皮亚诺曲线距离求解

C蓝桥杯皮亚诺曲线距离求解 一、题目概述二、解题分析2.1解题思路2.2k值范围限制 三、实现代码四、代码测试4.1蓝桥杯测试平台4.2直接传入原始输入的k值4.3限制k值大小4.4pow函数求整数高次幂存在误差4.5满分代码 附录error: ‘long long int y1’ redeclared as different kin…

开源!速度100Kb/s的有线和无线双模ESP32S3芯片的DAP-Link调试器

开源&#xff01;速度100Kb/s的有线和无线双模ESP32S3芯片的DAP-Link调试器 目录 开源&#xff01;速度100Kb/s的有线和无线双模ESP32S3芯片的DAP-Link调试器本项目未经授权&#xff0c;禁止商用&#xff01;本项目未经授权&#xff0c;禁止商用&#xff01;本项目未经授权&…

简记_硬件系统设计之需求分析要点

目录 一、 功能需求 二、 整体性能需求 三、 用户接口需求 四、 功耗需求 五、 成本需求 六、 IP和NEMA防护等级需求 七、 认证需求 功能需求 供电方式及防护 供电方式&#xff1a;市电供电、外置直流稳压电源供电、电池供电、PoE&#xff08;Power Over Ether…

python连接deepseek api实例

步骤一&#xff1a;安装必要的库&#xff0c;如openai&#xff1b; 步骤二&#xff1a;deepseek平台申请api&#xff0c;并充值&#xff08;可先充10元&#xff09;&#xff0c;费用大概一个查询2分钱的样子&#xff1b; 步骤三&#xff1a;设置环境变量&#xff1a;DEEPSEEK…

抽象类与普通类

抽象类和普通类的区别&#xff1a; 抽象类其实就是普通类和接口&#xff08;完全抽象&#xff09;之间的设计工具。通过抽象类&#xff0c;可以更灵活地构建可扩展、可维护的类层次结构。抽象类的核心价值在于平衡代码复用和规范约束。 示例&#xff1a;

免费生成可下载ppt

1.天工AI 免费的&#xff0c;模版很少&#xff0c;效果不是很好&#xff1b; 2.Kimi 免费的&#xff0c;模版不多&#xff0c;效果还可以&#xff1b;