现在的位置: 首页 > 综合 > 正文

xv6自旋锁

2012年07月11日 ⁄ 综合 ⁄ 共 1124字 ⁄ 字号 评论关闭

     在多核和多线性的系统中,需要注意访问安全,即需要考虑不同的CPU和多线程之间因竞争而存在的互斥关系。比如下面的例子:

 

考虑多核的情况:如果多个CPU在第16行之前同时访问第15行,那么后面CPU的赋值会将前面CPU的赋值覆盖

考虑多线程的情况:如果第一个线程执行完15行之后,时钟中断,切换到第二个线程并恰好也执行第15行,则也会发生冲突

因此,对于上述情况,我们应该每次仅仅允许单个访问,可以通过互斥来实现独占的访问。

 

以上面的为例子,使用互斥锁的一种最常见的形式是:

 

即在即将访问临界资源的时候,取得锁;在访问完后,释放锁。

 

接下来的问题,是如果实现acquire函数,即获取锁的操作,考虑下面的方法

 

这是一个朴素的想法,但是这种方法存在问题,因为如果lk->locked为0时。第一个线程进入到if内,正打算执行lk->locked = 1,这时发生了一个时钟中断,切换到第二个线程。对于第二个线程,这时ik->lock依旧为0,因此也会进入到if语句内。

为什么会产生这样的情况呢?主要是因为判断和条件语句有可能分隔执行,即这两个不是原子操作。

 

可以使用x86的硬件指令xchg来实现原子操作,xv6操作系统中的自旋锁就是采用的这种方式:

  

在需要获取锁的时候,只有当有人释放锁使得lk->locked为0时,xchg才会返回0,同时使得lk->locked又变成1,离开while循环,否则一直繁忙等待 (这也是自旋锁效率不高的一个原因哈)。

 

 

 

 

 

 

 

 

抱歉!评论已关闭.