操作系统层面的锁

线程安全的临界区通常通过锁机制保证,锁的获取和释放需原子操作避免并发冲突。硬件指令如TAS和CAS提供原子操作支持,确保同一时刻只有一个线程能访问临界区。锁的实现依赖于操作系统和CPU,通过禁止中断或特定硬件指令避免多线程同时获取锁,从而实现线程安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

线程安全的临界区需要依靠锁,而锁的获取必须也要保证自己是线程安全的,也就是说,不能出现两个线程同时得到锁的情况,那么锁是如何保证自己是线程安全的呢?或者说,在操作系统以及CPU层面,锁是如何实现的?

锁的本质

多个进程同时访问某公共变量要进行临界区的互斥访问,不然容易发生冲突,或者集群状态下为了保证各个节点的数据一致性也需要进行同步,实现同步一般都通过锁机制(包括信号量)来完成。但任何锁,追究到底层,都要由操作系统的原子操作来保证

实际上锁就是一个变量,通过这个变量的值来判断是不是已加锁,比如可以定义变量lock=1表示未被加锁,lock=0表示已加锁。那么加锁过程可以描述为:判断变量lock是否等于1,如果lock=1,则将lock改为0表示已加锁,然后进入临界区。这时别的线程也想进入临界区,一判断lock=0,那么将不被允许进入临界区,直到拥有锁的线程释放锁lock,即将lock改为1。

锁的实现

如果不加任何限制条件,我们可能会发现,这样的方式会造成一些冲突:
线程a想要进入临界区,判断lock=1,可以进入临界区,此时在另一个cup核执行的线程b也判断lock=1,也会进入临界区,这样两个线程都会访问临界变量,发生冲突。

锁是如何保证同一时刻只有一个线程(协程)访问临界区的,这涉及到锁的具体实现。
最简单的方法禁用中断就可以,而且要禁用所有cup核的中断。这就是解决思路,但是实际并不是这么操作的,因为屏蔽中断会导致系统效率低下
一般来说,锁的实现依赖底层的硬件指令,TAS(Test And Set)和 CAS(Compare And Set)是其中两个被广泛使用的硬件指令。
Test And Set
TAS指令的语义是:向某个内存地址写入值1,并且返回这块内存地址存的原始值。TAS指令是原子的,这是由实现TAS指令的硬件保证的(这里的硬件可以是CPU,也可以是实现了TAS的其他硬件)。

同TAS一样,CAS也是由硬件支持的原子操作。在x86架构中,CAS对应的汇编指令是CMPXCHG。
CAS的语义是:比较某个内存地址的值与一个给定值(这个给定值是上一刻从此内存地址读出来的),如果相等,则把一个新值写入到此内存地址

这些硬件支持的指令会阻塞其他cpu核对相关内存的缓存块的访问,从而达到原子效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值