如果有交互的公共数据区域,我们需要让一个进程先执行,一个进程后执行,互斥锁就是用锁的方式让他们的竞争关系变得有序。
临界区问题
临界区是在程序之间有公共数据交互时产生的区域,没有两个进程可以在它们各自的临界区同时执行
临界区的i协议
临界区管理准则
临界区必须有一个进程,因为如果临界区为空且满足互斥性那么其他进程都无法在临界区运行,临界区运行的程序也不能一直占用临界区,必须要让其他进程等待时间为有限的。
喂养金鱼问题
上面代码还是会有问题
那么这段代码的临界区在哪里
这楼里fish和feed变量都是公共的,所以这块区域就是临界区
我们修改这段伪代码,将异步尝试转为同步
这里这个note代表一个记号,表示正在判断是否喂鱼,remove note走时候撕掉记号。
但上个代码还是有问题
我们再次修改伪代码
但这里金鱼就不是撑死了,是饿死了
违反了有空让进原则
那么对于计算机系统来说,饿死好,还是撑死好呢?
对于计算机数据来说,我认为是饿死更好,因为撑死就等于数据被修改为错误了,而饿死代表计算机的数据并没有被修改。
我们再次修改伪代码
空循环,让alice等待tom移除note
我们再次分析
这里我自己对这个代码分析了一下:tom要执行需要满足alice没留下note,一但留下note,tom就无法喂食,而alice是一定会喂食的,所以这里需要alice这个设备性能比tom好
这两个算法和上面的算法思想是差不多的
互斥锁
一个进程拿到锁,其他进程如果与这个进程互斥,那么再要取得锁的使用权,就会进入loop状态,进程使用完需要释放锁
上锁和测试是不能被打断的
既然我们知道了上锁和测试是不可以被打断的,我们引用一个原子操作的概念
解决浪费cpu周期的缺点,我们可以将这个等待进程进入等待队列里,但是我们要注意,万一自旋的时间比切换队列消耗的时间更久,那么这个操作反而浪费了资源。