xv6中专门讲锁的篇幅并不多,锁的代码也在一两行左右,但是锁的使用却是无处不在的,而且要理解好也并不那么容易
对锁的需求来自于interleaving(交错执行),这可能是多处理器环境下,也可能是单处理器环境下在不同进程/线程间切换cpu
为什么单处理器下需要锁?很多你以为的操作并不是原子的,比如a+=1,首先是取出a的值,然后加1,然后赋值给a
如果在赋值之前,因为抢占式调度,cpu选择的另一个进程修改了a的值,那么重新调度回去,完成对a的赋值之后,之前的修改就会丢失
当他们需要访问共享的数据结构时,就出现了问题,如:
- 一个进程在读一个数据时,可能另一个进程正在修改它,那么这个进程读到的数据就可能是不正确的
- 多个进程同时更新一个数据,那么可能只有最后完成的更新保留了下来,之前的更新都丢失了
例如:

这样一个数据结构,list指向第一个节点(invariant),push新建一个节点,并将其插入到最前面,然后让list重新指向他
考虑下面情况:

此时c1这个节点就没有被插入到链表中去,发生这个错误的原因在于:同时执行15行违反了上述invariant,其他一个插入时,list没有指向第一个节点
当然上述只是一种可能的情况,也有可能先执行15行的,也先执行完了16行,之后另一个进程再执行15行,此时就没有问题,也就是说这个bug是

本文介绍了xv6操作系统中锁的实现,包括死锁、锁与中断的关系以及睡眠锁。通过分析并发执行导致的问题,阐述了锁的必要性,讲解了自旋锁和睡眠锁的工作原理,以及如何防止死锁和指令重排带来的影响。
最低0.47元/天 解锁文章
524

被折叠的 条评论
为什么被折叠?



