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

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

相关文章

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR

Java实现MD5加密的四种方式

《Java实现MD5加密的四种方式》MD5是一种广泛使用的哈希算法,其输出结果是一个128位的二进制数,通常以32位十六进制数的形式表示,MD5的底层实现涉及多个复杂的步骤和算法,本文给大家介绍了Ja... 目录MD5介绍Java 中实现 MD5 加密方式方法一:使用 MessageDigest方法二:使用

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

Rust中的BoxT之堆上的数据与递归类型详解

《Rust中的BoxT之堆上的数据与递归类型详解》本文介绍了Rust中的BoxT类型,包括其在堆与栈之间的内存分配,性能优势,以及如何利用BoxT来实现递归类型和处理大小未知类型,通过BoxT,Rus... 目录1. Box<T> 的基础知识1.1 堆与栈的分工1.2 性能优势2.1 递归类型的问题2.2