自旋锁保持时间非常短(如何理解自旋锁)

作者| 慕课网精英讲师 咚咚呛

最近总有同学问我:

对自旋锁的介绍完全听不懂。我猜,这是一种线程的锁定,直到这个线程不用这个资源了,才会彻底解锁,让出线程。但是希望得到严谨的解答,谢谢。

这个问题要从自旋锁的实现去回答。自旋锁是用于多线程同步的一种锁,线程反复检查锁变量是否可用。由于线程在这一过程中保持执行,因此是一种忙等待,也即是名字中“自旋”本身的含义。

自旋锁在不同语言都有不同的实现,但核心逻辑都是一样的,你可以看做是一个死循环去判断锁变量是否可用,如果可用则跳出循环,否则继续死循环。

逻辑如下:

void spin_lock(lock)

{

while (test_and_set(lock, true));// 锁可用则返回,否则继续循环

}

生产者每次加一前后都会加锁和解锁,那解锁后,锁变量可用,消费者线程就有机会进行减一操作了。那不就是和互斥锁一样了吗?

自旋锁保持时间非常短(如何理解自旋锁)(1)

是的,就锁的使用上,自旋锁的使用方式和互斥锁的使用并无太大区别,但需要注意的是,自旋锁等待的过程是100%一个核的CPU的,也即是不会让出CPU,这一点和其他锁不同。这一点在课程中,有详细的演示。

既然这种锁会100%占用CPU,那为什么计算机需要有自旋锁这种锁,对计算机的性能有什么好处呢?

这是好问题,为什么计算机内部的实现需要自旋锁,这需要联系前面学习的知识。

通过前面的学习我们知道,进程或者线程在运行的时候,是有上下文的,当不同线程进行切换的时候,为了让线程可以运行起来,需要很多的准备工作,这个准备工作,我们称为“上下文切换”。

在CPU的一个核中,每秒钟可会进行万级~十万级别的上下文切换次数,每次上下文切换都需要一定的成本,因此频繁的上下文切换会对计算机性能造成较大的影响。

锁的好处就是它只是忙等待,线程始终在运行,相比互斥锁的使用,避免了上下文切换。

所以这也限定了互斥锁的使用范围,如果互斥锁等待的时间过长,那么由于它本身对CPU的占用,会导致别的线程无法使用CPU。

因此,互斥锁适用于可预见等待时间很短的多线程同步场景,而对于等待时间不可预测或者等待时间很长的场景,仍然是互斥锁具备更高的效率。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页