并发编程中的各类锁

devtools/2024/10/19 7:28:06/

引言
在并发编程中,锁是一种关键的同步机制,用于控制多个线程对共享资源的访问。不同类型的锁在不同的场景下有着不同的适用性和性能特点。本文将探讨几种常见的锁,包括互斥锁、自旋锁、读写锁、悲观锁和乐观锁,并对它们进行详细总结和比较。

1. 互斥锁(Mutex Lock)
互斥锁是最常见的一种锁机制,用于保护共享资源在任意时刻只能被一个线程访问。当一个线程获取到互斥锁时,其他线程需要等待该线程释放锁后才能访问共享资源。

2. 自旋锁(Spin Lock)
自旋锁是一种忙等待的锁机制,当线程尝试获取锁时,如果锁已经被其他线程占用,该线程会循环等待直到锁可用。自旋锁适用于锁被占用时间较短的情况,避免了线程切换的开销。

3. 读写锁(Read-Write Lock)
读写锁允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。读写锁在读多写少的场景下能够提高并发性能,但在写多读少的情况下可能导致写线程长时间等待。另外,根据实现的不同,读写锁可以分为读优先锁和写优先锁。

读优先锁
读优先锁期望的是,读锁能被更多的线程持有,以便提高读线程的并发性,它的工作方式是:当读线程 A 先持有了读锁,写线程 B 在获取写锁的时候,会被阻塞,并且在阻塞过程中,后续来的读线程 C 仍然可以成功获取读锁,最后直到读线程 A 和 C 释放读锁后,写线程 B 才可以成功获取写锁。

写优先锁
写优先锁是优先服务写线程,其工作方式是:当读线程 A 先持有了读锁,写线程 B 在获取写锁的时候,会被阻塞,并且在阻塞过程中,后续来的读线程 C 获取读锁时会失败,于是读线程 C 将被阻塞在获取读锁的操作,这样只要读线程 A 释放读锁后,写线程 B 就可以成功获取写锁。

但不管优先读锁还是写锁,对方可能会出现饿死问题,那么我们就不偏袒任何一方,搞个公平读写锁。公平读写锁比较简单的一种方式是:用队列把获取锁的线程排队,不管是写线程还是读线程都按照先进先出的原则加锁即可,这样读线程仍然可以并发,也不会出现「饥饿」的现象。

4. 悲观锁(Pessimistic Lock)
悲观锁假设并发访问的情况下会发生冲突,因此在访问共享资源之前先获取锁。互斥锁、自旋锁和读写锁都属于悲观锁的范畴。

5. 乐观锁(Optimistic Lock)
乐观锁假设并发访问的情况下不会发生冲突,因此在访问共享资源之前不会加锁,而是在更新操作时进行版本号或者时间戳的比较来判断是否发生冲突。乐观锁适用于读多写少的情况下,避免了大量的锁竞争。

总结和比较

  • 互斥锁适用于对共享资源的访问需要排他性的情况。
  • 自旋锁适用于锁被占用时间短且线程竞争激烈的情况。
  • 读写锁适用于读多写少的场景,能够提高并发性能。
  • 悲观锁假设并发访问时会发生冲突,因此需要在访问前获取锁。
  • 乐观锁假设并发访问时不会发生冲突,适用于读多写少的情况。

结论:
对于并发编程中的锁机制,选择合适的锁类型至关重要。不同类型的锁在不同场景下有着不同的适用性和性能特点,开发人员需要根据实际情况进行选择和使用。


http://www.ppmy.cn/devtools/28328.html

相关文章

paddleocr C++生成dll

目录 编译完成后修改内容: 新建ppocr.h头文件 注释掉main.cpp内全部内容,将下面内容替换进去。ppocr.h需要再环境配置中包含进去头文件 然后更改配置信息,将exe换成dll 随后右击重新编译会在根目录生成dll,lib文件。 注意这些dll一个也不能少。生成…

【电路笔记】-石英晶体振荡器

石英晶体振荡器 文章目录 石英晶体振荡器1、概述2、石英晶体等效模型3、石英晶体振荡器示例14、Colpitts 石英晶体振荡器5、Pierce振荡器6、CMOS晶体振荡器7、微处理器水晶石英钟8、石英晶体振荡器示例21、概述 任何振荡器最重要的特性之一是其频率稳定性,或者换句话说,其在…

聚醚醚酮(Polyether Ether Ketone)PEEK在粘接使用时可以使用UV胶水吗?要注意哪些事项?

一般情况下,聚醚醚酮(Polyether Ether Ketone,PEEK)是一种难以黏附的高性能工程塑料,而UV胶水通常不是与PEEK进行粘接的首选方法。PEEK表面的化学性质和高温性能使得它对常规胶水的附着性较低。然而,有一些…

【JavaScript】使用 AbortController 对象中断 fetch 的文本流传输

AbortController 正如我们所知道的,fetch 返回一个 promise。JavaScript 通常并没有“中止” promise 的概念。那么我们怎样才能取消一个正在执行的 fetch 呢?例如,如果用户在我们网站上的操作表明不再需要某个执行中的 fetch。 为此有一个…

acwing算法提高之数学知识--筛质数、分解质因数和快速幂

目录 1 介绍2 训练 1 介绍 本博客用来记录筛质数、分解质因数和快速幂相关的题目。 2 训练 题目1&#xff1a;1292哥德巴赫猜想 C代码如下&#xff0c; #include <iostream> #include <cstring> #include <algorithm> #include <set>using namesp…

模型训练中的过拟合和欠拟合

基本概念 我们知道&#xff0c;所谓的神经网络其实就是一个复杂的非线性函数&#xff0c;网络越深&#xff0c;这个函数就越复杂&#xff0c;相应的表达能力也就越强&#xff0c;神经网络的训练则是一个拟合的过程。   当模型的复杂度小于真实数据的复杂度&#xff0c;模型表…

Dynamic-Programming

目录 前言 引入 1) Fibonacci 2) 最短路径 - Bellman-Ford 3) 不同路径-Leetcode 62 4) 0-1 背包问题 降维 5) 完全背包问题 降维 6) 零钱兑换问题-Leetcode322 降维 零钱兑换 II-Leetcode 518 7) 钢条切割问题 降维 类似题目 Leetcode-343 整数拆分 8) 最长…

018、Python+fastapi,第一个Python项目走向第18步:ubuntu24.04 安装cuda和pytorch环境

一、说明 我们安装了pytorch环境之后&#xff0c;会用yolo v9 来测试一下&#xff0c;看8g 显存能不能跑下来&#xff0c;上次用无影云电脑&#xff0c;4cpu8g内存直接爆了&#xff0c;云电脑也死机了&#xff0c;提示一直占用内存不释放&#xff0c;我自己的云电脑不能占用内…