互斥锁、条件锁、读写锁和自旋锁

  1. 互斥锁(Mutex)
    概念
    互斥锁(Mutex,全称 mutual exclusion lock)是最基本的线程同步机制,用于防止多个线程同时访问共享资源。它保证在同一时刻,只有一个线程可以访问临界区(即需要互斥访问的代码段)。

工作原理

当一个线程试图进入临界区时,它会尝试获取互斥锁。如果锁已经被其他线程持有,该线程将被阻塞,直到锁被释放。

当持有锁的线程完成对临界区的访问后,释放锁,从而允许其他等待的线程获取锁。

适用场景

适用于需要对共享资源进行独占访问的场景,例如更新共享变量、操作文件等。

优点

简单直接,确保数据一致性。

缺点

阻塞线程会导致上下文切换开销,影响性能。

  1. 条件锁(Condition Variable)

概念

条件锁(Condition Variable)通常与互斥锁结合使用,用于在线程之间同步某种条件。例如,一个线程等待某个条件成立,而另一个线程负责在条件满足时通知等待线程。

工作原理

一个线程在持有互斥锁的情况下,可以调用 wait() 方法进入等待状态,并释放互斥锁。

另一个线程改变共享状态后,可以调用 notify() 或 notify_all() 来唤醒一个或所有等待线程。

被唤醒的线程会重新获取互斥锁,并检查条件是否满足,满足则继续执行,不满足则继续等待。

适用场景

适用于需要线程间协调的场景,例如生产者-消费者问题,一个线程等待资源可用,另一个线程通知资源可用。

优点

提供灵活的线程同步方式,避免忙等待。

缺点

实现复杂,涉及线程的等待和唤醒,可能导致虚假唤醒问题。

  1. 读写锁(Read-Write Lock)

概念

读写锁允许多个线程同时读取共享资源,但在有线程写入资源时,必须独占访问。它的目标是提高读多写少场景下的并发性能。

工作原理

读锁:多个线程可以同时获取读锁,只要没有线程持有写锁。

写锁:当一个线程获取写锁时,所有其他线程(包括读线程和写线程)都会被阻塞,直到写锁释放。

适用场景

适用于读多写少的场景,如缓存、配置信息读取等。

优点

提高了读多写少场景下的并发性能。

缺点

如果读写比例不平衡,或者写操作频繁,可能导致读写锁退化为普通的互斥锁,影响性能。

  1. 自旋锁(Spinlock)

概念

自旋锁是一种轻量级的锁机制,它在尝试获取锁时,不会立即阻塞线程,而是反复检查锁的状态(自旋),直到获取锁或条件满足。

工作原理

当一个线程尝试获取自旋锁时,如果锁已被占用,线程不会被挂起,而是在一个循环中不断检查锁是否可用。

一旦锁被释放,线程可以立即获取锁并进入临界区。

适用场景

适用于锁的持有时间非常短的场景,因为自旋锁避免了线程阻塞和上下文切换的开销。

适用于多核 CPU,能够有效利用 CPU 的缓存一致性机制。

优点

在锁的持有时间极短的情况下,性能优于互斥锁,因为避免了上下文切换。

缺点

如果锁持有时间较长,自旋将消耗 CPU 资源,导致性能下降。

不适合单核 CPU 系统,因为在自旋期间,其他线程无法获得执行机会。

总结

互斥锁:用于保护共享资源的独占访问,适用于大多数并发场景。

条件锁:用于线程间的条件同步,适用于需要协调线程之间执行顺序的场景。

读写锁:适用于读多写少的场景,提升并发性能。

自旋锁:适用于临界区非常短的场景,减少上下文切换开销。

互斥锁、自旋锁、信号量都是用于线程同步的工具,可以防止竞态条件。

互斥锁和自旋锁都是用于保护临界区的工具,但互斥锁会阻塞线程,自旋锁则在锁短时间被持有的场景中更为高效。

信号量的功能更为广泛,可以控制对一个或多个资源的访问,既可以模拟互斥锁的功能(通过二元信号量),也可以控制对多个实例资源的访问(通过计数信号量)。

互斥量是实现互斥锁的一种数据结构。

同步锁是一个广泛的概念,包含所有用于线程同步的锁,包括互斥锁、读写锁等。

相关推荐
楼田莉子1 小时前
(3万字详解)Linux系统学习:深入了解Linux系统开发工具
linux·服务器·笔记·git·学习·vim
小蜗的房子2 小时前
Red Hat Enterprise Linux 7.9安装Oracle 11.2.0.4单实例数据库-图文详解
linux·运维·服务器·数据库·sql·oracle·数据库架构
野生程序员y2 小时前
Linux-常用命令
linux
失因9 小时前
SELinux 安全机制详解与管理
linux·运维·安全·centos
CtrlZ学习录10 小时前
安全引导功能及ATF的启动过程(五)
linux·安全·架构·开源·可信计算技术
芥子须弥Office11 小时前
从C++0基础到C++入门 (第二十五节:指针【所占内存空间】)
c语言·开发语言·c++·笔记
啊阿狸不会拉杆11 小时前
《算法导论》第 14 章 - 数据结构的扩张
数据结构·c++·算法·排序算法
阿雄不会写代码11 小时前
Amazon Linux 训练lora模型的方式
linux·运维·服务器
Q741_14712 小时前
如何判断一个数是 2 的幂 / 3 的幂 / 4 的幂 / n 的幂 位运算 总结和思考 每日一题 C++的题解与思路
开发语言·c++·算法·leetcode·位运算·总结思考
源代码•宸14 小时前
C++高频知识点(十八)
开发语言·c++·经验分享·多线程·互斥锁·三次握手·字节对齐