【发布时间】:2020-06-15 06:18:18
【问题描述】:
我正在查看自旋锁的this implementation,尤其是获取和释放函数:
void
acquire(struct spinlock *lk)
{
pushcli(); // disable interrupts to avoid deadlock.
if(holding(lk))
panic("acquire");
// The xchg is atomic.
// It also serializes, so that reads after acquire are not
// reordered before it.
while(xchg(&lk->locked, 1) != 0)
;
lk->cpu = cpu;
getcallerpcs(&lk, lk->pcs);
}
// Release the lock.
void
release(struct spinlock *lk)
{
if(!holding(lk))
panic("release");
lk->pcs[0] = 0;
lk->cpu = 0;
xchg(&lk->locked, 0);
popcli();
}
如果 xchg 函数是原子函数,pushcli() 和 popcli() 的用途是什么?原子性不会确保只有一个线程能够在任何实例中更改锁的值并且不会被中断吗?为什么我们必须显式禁用中断以防止死锁?
【问题讨论】:
-
如果中断处理程序在正常代码持有的情况下尝试获取锁,则可能会发生死锁。中断处理程序将永远在
while循环中旋转,因为它永远无法获得锁,因为主代码执行已暂停,因此没有机会释放它。 (假设这里是单个 cpu 核心。)
标签: c assembly concurrency operating-system spinlock