四种锁(互斥锁,递归锁,读写锁,自旋锁)

2024-04-09 22:52

本文主要是介绍四种锁(互斥锁,递归锁,读写锁,自旋锁),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.互斥锁(mutex):互斥锁是最常见的一种锁,用来保护共享资源的互斥访问。一次只有一个线程可以获得互斥锁。如果其他线程试图获得已经被锁定的互斥锁,他们将被阻塞,直到锁被释放
2.递归锁(recursive lock):递归锁是一种特殊的互斥锁,允许同一个线程多次获得同一个锁,而不会导致死锁。递归锁维护了一个锁的计数器和一个拥有锁的线程标识
3.读写锁(read-write lock):读写锁允许多个线程同时读取共享资源,但再写入时需要互斥访问,这可以提高在读操作远多于写操作的场景下的性能
4.自旋锁(spinlock):自旋锁是一种特殊的锁,当锁已经被其他线程获得时,尝试获得锁的线程将忙等待(在一个循环中不断尝试获得锁),而不是被阻塞,自旋锁适用于锁持有时间非常短的场景

//递归锁

#include <iostream>
#include <thread>
#include <mutex>
struct Complex
{std::recursive_mutex mutex;int i;Complex() : i(0){}void mul(int x){std::lock_guard<std::recursive_mutex> lock(mutex);i *= x;}void div(int x){std::lock_guard<std::recursive_mutex> lock(mutex);i /= x;}void both(int x, int y){std::lock_guard<std::recursive_mutex> lock(mutex);mul(x);div(y);}
};
int main(void)
{Complex complex;complex.both(32, 23); //因为同一线程可以多次获取同一互斥量,不会发生死锁std::cout << "main finish\n";return 0;
}

互斥锁阻塞和唤醒的原理
1.当一个线程尝试获取互斥锁时,线程库会先查该锁是否已经被其他线程持有
2.如果锁没有被持有,线程库会将锁分配给线程,然后线程可以继续执行
3.如果锁已经被其他线程持有,线程会将请求线程挂起,挂起的线程会移除CPU的调度队列,进入等待队列,直到锁被释放。这样可以确保挂起的线程不会消耗CPU的资源
4.当持有锁的线程完成对共享资源的操作并释放锁之后,线程库会从等待队列中选择一个或多个挂起的线程,并将它们重新加入调度队列
5.被唤醒的进程会尝试重新获取锁,如果成功,线程会继续执行,否则,线程将再次被挂起,等待下一次通知

这篇关于四种锁(互斥锁,递归锁,读写锁,自旋锁)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/889429

相关文章

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

Java实现本地缓存的四种方法实现与对比

《Java实现本地缓存的四种方法实现与对比》本地缓存的优点就是速度非常快,没有网络消耗,本地缓存比如caffine,guavacache这些都是比较常用的,下面我们来看看这四种缓存的具体实现吧... 目录1、HashMap2、Guava Cache3、Caffeine4、Encache本地缓存比如 caff

Python lambda函数(匿名函数)、参数类型与递归全解析

《Pythonlambda函数(匿名函数)、参数类型与递归全解析》本文详解Python中lambda匿名函数、灵活参数类型和递归函数三大进阶特性,分别介绍其定义、应用场景及注意事项,助力编写简洁高效... 目录一、lambda 匿名函数:简洁的单行函数1. lambda 的定义与基本用法2. lambda

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python获取浏览器Cookies的四种方式小结

《Python获取浏览器Cookies的四种方式小结》在进行Web应用程序测试和开发时,获取浏览器Cookies是一项重要任务,本文我们介绍四种用Python获取浏览器Cookies的方式,具有一定的... 目录什么是 Cookie?1.使用Selenium库获取浏览器Cookies2.使用浏览器开发者工具

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

SQL Server配置管理器无法打开的四种解决方法

《SQLServer配置管理器无法打开的四种解决方法》本文总结了SQLServer配置管理器无法打开的四种解决方法,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录方法一:桌面图标进入方法二:运行窗口进入检查版本号对照表php方法三:查找文件路径方法四:检查 S