C++多线程学习[五]:RAII锁

一、什么是RAII

使用局部对象来控制资源的技术,即它的生命周期由操作系统来管理,无需人工的介入。
为什么要采用RAII技术呢? 主要是在开发过程中资源的销毁容易忘记,容易造成死锁或内存泄露。

{}为一个区域 ,这里锁的是一块区域。不用在冗余的写mutex.lock()和mutex.unlock();

二、手动实现RAII管理mutex资源

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

class Tmutex
{
public:
	Tmutex(mutex& mtx) : mtx_(mtx)
	{
		cout << "Lock" << endl;
		//mtx_.lock();
	}

	~Tmutex()
	{
		cout << "UnLock" << endl;
		//mtx_.unlock();
	}
private:
	mutex &mtx_;
};

static mutex mtx;
void Test(int i)
{
	Tmutex lock(mtx);
	if (i == 1)
	{
		cout << " i = 1 " << endl;
	}
	else if (i == 2)
	{
		cout << " i = 2" << endl;
	}
	else 
	{
		cout << " i = " <<i<< endl;
	}

}

int main() 
{
	Test(1);
	Test(2);
	Test(3);
	return 0;
}

在这里插入图片描述

在这种方式中,lock 是一个对象,它被定义为互斥锁 mtx 的一个“保护者”(guard)。当创建 lock 对象时,在其构造函数中会自动执行 mtx.lock() 方法,从而获取互斥锁,确保当前线程拥有了对共享资源的独占访问权。而在 lock 对象生命周期结束时,其析构函数会自动调用 mtx.unlock() 方法,从而释放互斥锁,确保其他线程可以继续访问共享资源。

三、C++11 RAII控制锁lock_guard

在这里插入图片描述
可以看到 lock_guard源码中的构造会自动上锁,析构会自动解锁。

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

using namespace std;

static mutex mtx;

void Test(int i)
{
	lock_guard<mutex> lock(mtx);
	for (;;)
	{
		cout << i << endl;
		this_thread::sleep_for(500ms);
	}
}
int main() 
{
	for (int i = 0; i < 3; i++)
	{
		thread th(Test, i + 1);
		th.detach();
	}
	getchar();
	return 0;
}

在这里插入图片描述
这里三个线程,但是i = 2 这个线程被锁住,

当然它还有另一个构造函数,adopt_lock_t用来判断是否已经上锁。
在这里插入图片描述
在这里,因为lock_guard锁的区域并没有检查到是否上锁,因此会报错。
(和下面unique_lock一样)
在这里插入图片描述

在这里插入图片描述
我们在他之前锁上
在这里插入图片描述

这里它检测到前面已经上锁,因此会通过。

四、unique_lock

在这里插入图片描述
源码中有四个构造函数。
主要的是后三个(括号内指的是unique_lock对象)

  • adopt_lock 文章前面涉及到(已经拥有锁,不加锁,出栈区后会释放)

  • defer_lock (延后拥有锁,不加锁,出栈区后不释放,加锁后,退出栈区释放)
    在这里插入图片描述
    在这里插入图片描述
    锁加在哪里都可以,这里3个线程都延时后i = 2 的先上锁。 因为不释放,所以不加锁的话这3个线程会一直运行,而不发生阻塞,直到其中一个被上锁。

  • try_to_lock(尝试获得互斥的所有权而不阻塞,获取失败退出栈区不会释放,通过owns_locc()函数判断 )
    在这里插入图片描述
    如果已经锁上,会尝试读取是否上锁,因为前面已经上锁,因此它不会再次上锁,所以进入else情况

当然它也可以自己上锁
在这里插入图片描述

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

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

相关文章

JVM 性能调优 - 参数调优(3)

查看 JVM 内存的占用情况 编写代码 package com.test;public class PrintMemoryDemo {public static void main(String[] args) {// 堆内存总量long totalMemory Runtime.getRuntime().totalMemory();// jvm 试图使用的最大堆内存long maxMemory Runtime.getRuntime().maxM…

Matlab使用点云工具箱进行点云配准

一、代码 source_pc pcread(bun_zipper.ply); target_pc pcread(bun_zipper2.ply); % 下采样 gridStep 0.001; ptCloudA pcdownsample(source_pc,gridAverage,gridStep); ptCloudB pcdownsample(target_pc,gridAverage,gridStep); % 初始变换矩阵 tform_initial affine3…

AE2023 After Effects 2023

After Effects 2023是一款非常强大的视频编辑软件&#xff0c;提供了许多新功能和改进&#xff0c;使得视频编辑和合成更加高效和灵活。以下是一些After Effects 2023的特色功能&#xff1a; 新合成预设列表&#xff1a;After Effects 2023彻底修改了预设列表&#xff0c;使其…

Excel——有效性、二级菜单联动

一、录入规范数据 1.手动输入序列录入有效性信息 选择需要录入有效性的所有单元格 选择【数据】——【有效性】——【有效性】 在【允许】输入的值之间选择【序列】 在【序列】输入框中输入想要选择的值&#xff0c;中间用逗号&#xff08;必须是英文逗号&#xff09;隔开 。…

Java入门之JavaSe(韩顺平p1-p?)

学习背景&#xff1a; 本科搞过一段ACM、研究生搞了一篇B会后&#xff0c;本人在研二要学Java找工作啦~~&#xff08;宇宙尽头是Java&#xff1f;&#xff09;爪洼纯小白入门&#xff0c;C只会STL、python只会基础Pytorch、golang参与了一个Web后端项目&#xff0c;可以说项目小…

Linux 网络:PTP 简介

文章目录 1. 前言2. PTP(Precision Time Protocol​) IEEE 1588 协议简介2.1 PTP IEEE 1588 协议时间同步原理2.2 PTP IEEE 1588 协议时钟类型2.2.1 普通时钟(OC: Ordinary Clock)2.2.2 边界时钟(BC: Boundary Clock)2.2.3 透明时钟(TC: Transparent Clock)2.2.3.1 端对端透明时…

挂耳耳机哪个牌子好?推荐几款性价比超高的挂耳耳机

在寻求更轻便舒适的听音体验时&#xff0c;挂耳耳机逐渐成为众多用户的优先选择。市场上各式各样的耳挂耳机琳琅满目&#xff0c;种类繁多&#xff0c;挂耳耳机哪个牌子好&#xff1f;为了帮助大家更好地了解耳挂耳机的市场状况&#xff0c;我推荐几款性价比超高的挂耳耳机。 挂…

MongoDB的分片集群(二) :mongodb4.x分片集群离线搭建开启安全认证

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 相关文章&#xff1a; MongoDB的分片集群(一) : 基础知识 在《MongoDB的分片集群(一) : 基础知识》中梳理了分片集群的基础知识…

知名开发工具RubyMine全新发布v2023.3——支持AI Assistant

RubyMine 是一个为Ruby 和 Rails开发者准备的 IDE&#xff0c;其带有所有开发者必须的功能&#xff0c;并将之紧密集成于便捷的开发环境中。 RubyMine v2023.3正式版下载 新版本改进AI Assistant支持、Rails应用程序和引擎的自定义路径、对Rails 7.1严格locals的代码洞察、RB…

页面模块向上渐变显示效果实现

ps: 先祝各位朋友新春快乐 ^o^/ 想要首页不那么枯燥无味吗&#xff1f;还在未首页过于单调而苦恼吧&#xff0c;来试试这个吧&#xff08;大佬请忽略上述语句o&#xff09; 今天要实现一个页面线上渐变显示的效果&#xff0c;用来丰富首页等页面&#xff1a; 这里先随机建立几…

jsp商场会员卡管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 商场会员卡管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.…

C遗漏知识(个人向)

之前C语言遗漏的一些。 数据在内存中的存储 原码、反码、补码 整数的2进制表⽰⽅法有三种&#xff0c;即 原码、反码和补码 正整数的原、反、补码都相同。 负整数的三种表⽰⽅法各不相同。 原码&#xff1a;直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。 反码&…

【芯片设计- RTL 数字逻辑设计入门 6 -- 带同步复位的D触发器 RTL实现及testbench 验证】

文章目录 带同步复位的D触发器Verilog 代码testbench 代码编译及仿真问题小结 带同步复位的D触发器 同步复位 &#xff1a;复位只能发生在在clk信号的上升沿&#xff0c;若clk信号出现问题&#xff0c;则无法进行复位。 Verilog 代码 // timescale ins/1nsmodule flopr (inpu…

45 漏洞发现-API接口服务之漏洞探针类型利用修复

目录 端口服务类安全测试API接口-webservice RESTful APT 演示案例:端口服务类-Tomcat弱口令安全问题端口服务类-Glassfish任意文件读取其他补充类-基于端口WEB站点又测试其他补充类-基于域名WEB站点又测试其他补充类-基于IP配合端口信息再收集口令安全脚本工具简要使用-Snetcr…

sql求解连续两个以上的空座位

Q&#xff1a;查找电影院所有连续可用的座位。 返回按 seat_id 升序排序 的结果表。 测试用例的生成使得两个以上的座位连续可用。 结果表格式如下所示。 A:我们首先找出所有的空座位&#xff1a;1&#xff0c;3&#xff0c;4&#xff0c;5 按照seat_id排序&#xff08;上面已…

vue3 elementplus DateTimePicker 日期时间设置默认时间为当天

DateTimePicker里面有个自带属性 可以实现这个需求&#xff0c;如图&#xff1a; // 设置当前当天时间范围 00: 00: 00 - 23:59:59 const currentDate [setDefaultDate(0), setDefaultDate(1)]const setDefaultDate (type:number ): string > {let t ;let date new Da…

代码随想录算法训练营第25天 | 216.组合总和III ,17.电话号码的字母组合

回溯章节理论基础&#xff1a; https://programmercarl.com/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 216.组合总和III 题目链接&#xff1a;https://leetcode.cn/problems/combination-sum-iii/ 思路: 本题就是在[1,2,3,4,5,6,7,…

【宝藏系列】嵌入式入门概念大全

【宝藏系列】嵌入式入门概念大全 0️⃣1️⃣操作系统&#xff08;Operating System&#xff0c;OS&#xff09; 是管理计算机硬件与软件资源的系统软件&#xff0c;同时也是计算机系统的内核与基石。操作系统需要处理管理与配置内存、决定系统资源供需的优先次序、控制输入与输…

leetcode9. 回文数|详细深入讲解算法

前往题目有 反转一半数字 思路 映入脑海的第一个想法是将数字转换为字符串&#xff0c;并检查字符串是否为回文。但是&#xff0c;这需要额外的非常量空间来创建问题描述中所不允许的字符串。 第二个想法是将数字本身反转&#xff0c;然后将反转后的数字与原始数字进行比较&…

ERR_SSL_VERSION_OR_CIPHER_MISMATCH

我在namesilo买的域名&#xff0c;coludflare做的解析&#xff0c;华为云的SSL&#xff0c;用宝塔部署的SSL&#xff0c;访问https报错&#xff0c;http却正常&#xff1a; 报错&#xff1a;此网站无法提供安全连接www.hongkong.ioyunxin.top 使用了不受支持的协议。 ERR_SSL_…