保护共享资源的方法(互斥锁)
- 我最近开了几个专栏,诚信互三!
====> |||《算法专栏》::刷题教程来自网站《代码随想录》。|||
====> |||《C++专栏》::记录我学习C++的经历,看完你一定会有收获。|||
====> |||《Linux专栏》::记录我学习Linux的经历,看完你一定会有收获。|||
====> |||《C#专栏》::记录我复习C#的经历,深度理解,查漏补缺,不定期更新。|||
====> |||《计算机网络专栏》::记录我学习计算机网络,看完你一定会有收获。|||
保护共享资源的方法(锁)
- 保护共享资源要做到什么
- 什么是锁
- 为什么要有锁
- 锁的创建
- 锁的初始化
- 锁的销毁
- 加锁和解锁
- 以抢票系统了解锁的使用
保护共享资源要做到什么
我们要保护共享资源,我们其实无外乎做到两点即可。
1).互斥:及同一时间内只有一个执行流访问共享资源。
2).同步:及访问共享资源要有一定的顺序。
满足上述两点,则共享资源就被保护起来了,被称为临界资源。
什么是锁
锁是完成线程互斥的一种方法,它可以让共享资源在同一时间内,只被一个执行流访问。
锁的底层原理其实相当简单,我们可以将锁想象成一个整数1,只有线程拿到这个整数1,才可以执行后面的代码,否则就阻塞,在执行完后,再把锁还回去。
为什么要有锁
锁是线程进行互斥的常用手段,锁的存在让我们可以保护共享内存,让原本并发执行的线程串行执行,防止出现出乎意料的结果。
锁的创建
锁的创建其实是一个原生线程库的内置类型。
pthread_mutex_t
这就是锁类型,我们在对这个类型初始化就得到了一把锁。
要注意,如果锁是局部的,则需要使用初始化接口,如果是全局的锁,则可以使用宏PTHREAD_MUTEX_INITIALIZER来初始化。
锁的初始化
全局锁,使用宏初始化,局部锁,使用接口初始化。
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
参数1:代表初始化那个锁,要传入一个指针。
参数2:设置锁的属性,传入nullptr为默认属性。
锁的销毁
不论是全局锁还是局部锁,都需要使用接口销毁。
pthread_mutex_destroy(pthread_mutex_t *mutex)
参数1:直接指定某个锁,销毁
加锁和解锁
给某个线程加锁,只需要在该线程中对临界区加锁,保护共享资源就是保护访问共享资源的代码
加锁解锁要注意以下几点
1).加锁和解锁要尽量细致。
2).加锁后,加锁的部分可以视为“原子操作”
3).加锁后要注意解锁,不然多线程可能导致死锁问题
pthread_mutex_lock(pthread_mutex_t *mutex)
参数1:代表该线程加那把锁。
pthread_mutex_unlock(pthread_mutex_t *mutex)
参数1:代表该线程解那把锁
以抢票系统了解锁的使用
抢票逻辑中,票数是共享资源,我们的每个线程都需要一直抢票,但是对于抢票逻辑我们需要加锁,因为对共享资源的操作不是原子的,可能导致不可知的后果。
相关文章:

保护共享资源的方法(互斥锁)
我最近开了几个专栏,诚信互三! > |||《算法专栏》::刷题教程来自网站《代码随想录》。||| > |||《C专栏》::记录我学习C的经历,看完你一定会有收获。||| > |||《Linux专栏》࿱…...

树的非递归遍历(层序)
层序是采用队列的方式来遍历的 就比如说上面这颗树 他层序的就是:1 24 356 void LevelOrder(BTNode* root) {Que q;QueueInit(&q);if (root){QueuePush(&q, root);}while (!QueueEmpty(&q)){BTNode* front QueueFront(&q);QueuePop(&q);print…...
解决SpringBoot使用@Transactional进行RestTemplate远程调用导致查询数据记录为null的bug
开启事务过程中,如果远程调用查询当前已经开启但没有提交的事务,就会查不到数据。 示例代码 import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.annotation.Transactional; import o…...
pl/sql基础语法操作
oracle pl/sql语言(procedural language/sql)是结合了结构化查询与oracle自身过程控制为一体的强大语言。 语法执行块 语法结构: [ declare 可选 声明变量部分--declaration statements (1);]begin --执行部分--executable statements (2)…...
Vue 父组件向子组件传递数据
1、在子组件中,你需要声明你期望从父组件接收哪些props。这可以通过props选项完成,可以是一个数组或对象形式: export default {props: [message],props:{message:String }props: {message: String, // 类型检查count: {type: Nu…...

二十五、openlayers官网示例CustomOverviewMap解析——实现鹰眼地图、预览窗口、小窗窗口地图、旋转控件
官网demo地址: Custom Overview Map 这个示例展示了如何在地图上增加一个小窗窗口的地图并跟随着地图的旋转而旋转视角。 首先加载了一个地图。其中 DragRotateAndZoom是一个交互事件,它可以实现按住shift键鼠标拖拽旋转地图。 const map new Map({int…...
K8S Secret管理之SealedSecrets
1 关于K8S Secret 我们通常将应用程序使用的密码、API密钥保存在K8S Secret中,然后应用去引用。对于这些敏感信息,安全性是至关重要的,而传统的存储方式可能会导致密钥在存储、传输或使用过程中受到威胁,例如在git中明文存储密码…...
Gone框架介绍25 - Redis模块参考文档
文章目录 Redis 参考文档配置项import 和 bury使用分布是缓存 redis.Cache接口定义使用示例 使用分布式锁 redis.Locker接口定义使用示例 操作Key,使用 redis.Key接口定义 使用 Provider 注入 redis 接口使用示例 直接使用redis连接池接口定义使用示例 Redis 参考文…...
SpringBoot前置知识02-spring注解发展史
springboot前置知识01-spring注解发展史 spring1.x spring配置只能通过xml配置文件的方式注入bean,需要根据业务分配配置文件,通过import标签关联。 spring1.2版本出现Transactional注解 <?xml version"1.0" encoding"UTF-8"?> <be…...

C++ TCP发送Socket数据
DEVC需要加入ws2_32库 #include <iostream> #include <winsock2.h>#pragma comment(lib, "ws2_32.lib")void sendData(const char* ip, int port, const char* data) {WSADATA wsaData;SOCKET sockfd;struct sockaddr_in server_addr;// 初始化Winsock…...

鸿蒙HarmonyOS开发中的易混点归纳-持续补充中
相关文章目录 鸿蒙HarmonyOS开发术语全解:小白也能看懂! 文章目录 相关文章目录前言一、build()函数和Builder装饰器?二、自定义组件和系统组件(内置组件)三、组件和页面四、自定义弹窗和其他弹窗总结 前言 一、build…...

ue引擎游戏开发笔记(45)——添加游戏音效
1.需求分析: 截至目前,我们仍然在一个无声的世界游玩游戏,所以有必要为游戏增添一些声音,例如开火声,子弹撞击声等等。 2.操作实现: 1.这是一个较为简单的功能,类似特效的实现方法,…...

202472读书笔记|《首先你要快乐,其次都是其次》——快乐至上,允许一切发生
202472读书笔记|《首先你要快乐,其次都是其次》——快乐至上,允许一切发生 《首先你要快乐,其次都是其次》作者林小仙,挺轻松的小漫画,清新的文字。 生而为人,我很抱歉,大可不必。 生活已经很难…...

8.STL中Vector容器的常见操作(附习题)
目录 1.vector的介绍 2 vector的使用 2.1 vector的定义 2.2 vector iterator 的使用 2.3 vector 空间增长问题 2.3 vector 增删查改 2.4 vector 迭代器失效问题 2.5 vector 在OJ中的使用 1.vector的介绍 vector是表示可变大小数组的序列容器。 就像数组一样࿰…...

5.23小结
1.java项目创新 目前想添加一个自动回复的功能和设置验证方式有(允许任何人添加,禁止添加,设置回答问题添加,普通验证添加) 目前只完成画好前端界面,前端发送请求,还有表的修改 因为涉及表字…...

文心一言 VS 讯飞星火 VS chatgpt (265)-- 算法导论20.1 4题
四、假设不使用一棵叠加的度为 u \sqrt{u} u 的树,而是使用一棵叠加的度为 u 1 k u^{\frac{1}{k}} uk1的树,这里 k 是大于 1 的常数,则这样的一棵树的高度是多少?又每个操作将需要多长时间?如果要写代码…...
Flutter 中的 EditableText 小部件:全面指南
Flutter 中的 EditableText 小部件:全面指南 在Flutter中,EditableText是一个低级别的文本编辑组件,它提供了构建自定义文本编辑界面的能力。与TextField和TextFormField不同,EditableText提供了更多的灵活性,允许开发…...

H800基础能力测试
H800基础能力测试 参考链接A100、A800、H100、H800差异H100详细规格H100 TensorCore FP16 理论算力计算公式锁频安装依赖pytorch FP16算力测试cublas FP16算力测试运行cuda-samples 本文记录了H800基础测试步骤及测试结果 参考链接 NVIDIA H100 Tensor Core GPU Architecture…...
2024/5/24 Day38 greedy 435. 无重叠区间 763.划分字母区间 56. 合并区间
2024/5/24 Day38 greedy 435. 无重叠区间 763.划分字母区间 56. 合并区间 遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。如果两个维度一起考虑一定会顾此失彼。 重叠区间问题 435. 无重叠区间 题目链接 435 给定一个区间的集合 i…...
【python】使用函数名而不加括号是什么情况?
使用函数名而不加括号通常是为了表示对函数本身的引用,而不是调用函数。这种用法通常出现在下面这几种情况: 作为回调函数传递:将函数名作为参数传递给其他函数,以便在需要时调用该函数。例如,在事件处理程序或高阶函数…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...

Spring是如何实现无代理对象的循环依赖
无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见:mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简…...

timestamp时间戳转换工具
作为一名程序员,一款高效的 在线转换工具 (在线时间戳转换 计算器 字节单位转换 json格式化)必不可少!https://jsons.top 排查问题时非常痛的点: 经常在秒级、毫秒级、字符串格式的时间单位来回转换,于是决定手撸一个…...

深度学习学习率优化方法——pytorch中各类warm up策略
warm-up具体原理以及为什么这么做在之前的博客有介绍,这里直接介绍如何直接使用pytorch中的warm-up策略,在pytorch中对于warm-up所有支持的方法都有描述,可以直接阅读1。 深度学习中各类学习率优化方法(AdaGrad/RMSprop/Adam/Warm-UP)原理及其…...
【AI教我写网站-ECG datacenter】
阶段性总结:后端用户管理基础 在项目管理和协作中,清晰地阐述“为什么做”比“怎么做”更能凝聚共识和提供方向。我们不仅要理解技术实现,更要明白其背后的动机和意义。 让我们重新回顾并总结我们到目前为止的工作,这次会更侧重…...