互斥
实现原子指令用到了什么,一小段的不可被打断的指令
自旋锁,把1交换出去,其他的线程只能交换出0,并不断循环交换,临界区结束了之后把1还回去
另一个线程就把锁换过来
如果lock unlock函数加上参数,就相当于可以设多个锁,试图得到同一把锁的线程就实现了互斥
lock(&status)
1 | bool holding(spinlock_t *lk) {//当前是有锁状态,且锁的拥有者是当前cpu |
要正确使用锁很难,要经常使用断言,检查中断是否符合预测assert,可以读读xv6源码
在用户态
用户程序sum++拥有锁,被操作系统中断了,切换到了其他程序,
其他各个线程都无法获得锁,要等操作系统切回去
在操作系统中
会中断来实现锁
在操作系统内核:
连续上两次锁,中断一次再上锁,无法获得锁,就发生死锁
正确性准则
单处理器上锁解锁前后,中断状态不可改变,原来是中断还是中断,原来不中断还是不中断
多处理器,
使用栈保存中断状态
为了实现自旋一定要中断吗?
在用户态
因为自旋锁资源浪费严重
互斥锁(mutex)的实现使用了syscall,具有较好的scalability
futex如果没有锁直接访问,fast path
如何唤醒被syscall挂起的线程?
06-并发控制:互斥 (1)
自己思考一下,想各种情况,修改后可以立即用model checker来验证
互斥 2)
关中断+自旋实现互斥
保存锁前中断状态