计算机操作系统基础 (十二)--- 线程同步之自旋锁
引言
本文为第十二篇,线程同步之自旋锁,在上一篇文章介绍了互斥量,通过互斥量解决线程同步的问题。本文是另一个解决线程同步的方法---自旋锁
自旋锁
自旋锁的工作原理跟互斥量的工作原理其实是一模一样的,它也是在访问临界资源之前加一个锁,完成之后再将锁给释放掉。但是互斥量和自旋锁还是有一点区别的
自旋锁也是一种多线程同步的变量
使用了自旋锁的线程会反复检查锁变量是否可用,如果不可用就会循环反复的检查
因此自旋锁不会让出CPU,是一种忙等待状态
因此自旋锁其实就是:死循环等待锁被释放
自旋锁好处
自旋锁避免了进程或线程上下文切换的开销(如果这个锁占用的时间不是很长,这个代价还是很小的)
操作系统内部很多地方都是使用自旋锁,而不是互斥量
自旋锁不适合在单核CPU使用(因为自旋锁在等待的时候并不会释放CPU,如果在单核CPU使用的话会引起其它的进程或线程无法执行)
自旋锁和互斥量(锁)的比较
自旋锁是一种非阻塞锁,也就是说,如果某线程需要获取自旋锁,但该锁已经被其他线程占用时,该线程不会被挂起,而是在不断的消耗CPU的时间,不停的试图获取自旋锁
互斥量是阻塞锁,当某线程无法获取互斥量时,该线程会被直接挂起,该线程不再消耗CPU时间,当其他线程释放互斥量后,操作系统会激活那个被挂起的线程,让其投入运行
两种锁适用的场景
如果是多核处理器,如果预计线程等待锁的时间很短,短到比线程两次上下文切换时间要少的情况下,使用自旋锁是划算的
如果是多核处理器,如果预计线程等待锁的时间较长,至少比两次线程上下文切换的时间要长,建议使用互斥量
如果是单核处理器,一般建议不要使用自旋锁。因为,在同一时间只有一个线程是处在运行状态,那如果运行线程发现无法获取锁,只能等待解锁,但因为自身不挂起,所以那个获取到锁的线程没有办法进入运行状态,只能等到运行线程把操作系统分给它的时间片用完,才能有机会被调度。这种情况下使用自旋锁的代价很高
建议:如果加锁的代码经常被调用,但竞争情况很少发生时,应该优先考虑使用自旋锁,自旋锁的开销比较小,互斥量的开销较大
自旋锁的代码示例
执行结果
在快速变化的技术中寻找不变,才是一个技术人的核心竞争力。知行合一,理论结合实践
版权声明: 本文为 InfoQ 作者【书旅】的原创文章。
原文链接:【http://xie.infoq.cn/article/680beb44cbab575bb06537867】。文章转载请联系作者。
评论