多核操作系统中的自旋锁-『以XV6 & Linux 为例』

厚脸皮引流

自旋锁是一个很神奇的东西,一个介于高效和低效之间的一个 『薛定谔』?的互斥机制。

自旋锁的效率和它的应用场景有很大关系,在实际生产过程中,我们能在很多地方看见它的身影。

比如Linux kernal有挺多地方用到spinlock、 Nginx也有用到spinlock, 但很多时候自旋锁在很多场景下并不能很好的发挥出它的高效优势。

究竟什么时候我们应该使用SpinLock?

首先,要注意的是自旋锁只适用于多核心状态下(这个多核心指的是当前进程可用的核心数 > 1), 比如说你是一个8核Mac,但是你在一个限制1核的Docker环境中用SpinLock,卵用也没有!!!

本质上,SpinLock之所以有效就是假定,当前存在另外一个CPU核心正在使用你所需要的资源。CPU只有一个你等也是白等。 (就好像一个痴汉暗恋一个人一样,划掉?)

其次,SpinLock之所以在一些场景下很高效是因为旋等消耗的时钟周期远小于上下文交换产生的时间。

我们来回顾一下Mutex 睡眠等待的过程。首先是尝试上一次锁,如果不行的话就通过调度算法找到一个优先级更高的Thread,然后才是保存寄存器,写回被修改的数据,然后才是交换上下文。

可以看到这个代价是十分大的,而且交换上下文的代价是要✖️2的。一般来说,这个代价,在几千~几十万时钟周期。回顾一下一个4GHz的8代处理器,一个时间周期=0.25ns。交换一次的代价还是挺可观的。

所以我们使用SpinLock的时候就需要保证我们的临界区代码,能够在这个时钟周期之类完成所有任务。

所以一般spinLock等待的代码不会太长,一般几行(具体需要看芯片和编译环境),更不可能是I/O等待型的任务。(在XV6中,关于文件系统的操作都单独使用基于SpinLock的SleepLock)

然后,其实SpinLock更适合系统态,不太适合用户态。因为你用户态没法知道有没有另外一个CPU在处理你所需要的资源。而且SpinLock并不适合多线程抢占一个资源的场景,比如说开了60个线程抢占一个一个内存资源,这个竞争、等待的代价就是超级大的一个数。

所以,其实自旋锁的优势、劣势都很明显,怎么来更好的用好它就是程序员?‍?‍的事情啦。

SpinLock in XV6

XV6其实是一个很Unix的教学操作系统,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值