互斥

实现原子指令用到了什么,一小段的不可被打断的指令

自旋锁,把1交换出去,其他的线程只能交换出0,并不断循环交换,临界区结束了之后把1还回去

另一个线程就把锁换过来

如果lock unlock函数加上参数,就相当于可以设多个锁,试图得到同一把锁的线程就实现了互斥

lock(&status)

1
2
3
4
5
6
bool holding(spinlock_t *lk) {//当前是有锁状态,且锁的拥有者是当前cpu
return (
lk->status == LOCKED &&
lk->cpu == &cpus[cpu_current()]
);
}

要正确使用锁很难,要经常使用断言,检查中断是否符合预测assert,可以读读xv6源码

在用户态

用户程序sum++拥有锁,被操作系统中断了,切换到了其他程序,

其他各个线程都无法获得锁,要等操作系统切回去

在操作系统中

会中断来实现锁

在操作系统内核:

连续上两次锁,中断一次再上锁,无法获得锁,就发生死锁

正确性准则

单处理器上锁解锁前后,中断状态不可改变,原来是中断还是中断,原来不中断还是不中断

多处理器,

使用栈保存中断状态

为了实现自旋一定要中断吗?

在用户态

因为自旋锁资源浪费严重

互斥锁(mutex)的实现使用了syscall,具有较好的scalability

futex如果没有锁直接访问,fast path

如何唤醒被syscall挂起的线程?

06-并发控制:互斥 (1)

自己思考一下,想各种情况,修改后可以立即用model checker来验证

互斥 2)

关中断+自旋实现互斥

保存锁前中断状态