进程同步与信号量

进程同步

在这里插入图片描述
如上图,司机要想启动车辆,必须等待一个信号,
售货员在车关门之后,发送一个信号

  • 什么是进程同步?
    让进程走走停停来保证多进程合作的合理有序

只是发信号还不能解决全部问题,如下例
在这里插入图片描述
在这里插入图片描述

  • 引入信号量
    本来P2也应该被唤醒,所以只是用counter来决定还是不够的,也就是只是发信号还是不够的,需要一个量来记录一些信息,比如上例要记录等待了多少个进程
    在这里插入图片描述
    在这里插入图片描述
    信号量就是个整形变量
    如上图,P进程和C进程就根据信号量sem来决定要不要同步(等待,唤醒)
    在这里插入图片描述
    实现信号量
    在这里插入图片描述
    V的代码在P的基础上修改s.value++,<改为<=即可
  • 用信号量解决生产者-消费者问题
    在这里插入图片描述
    在这里插入图片描述
    mutex是互斥信号量,保证我在写文件时别人都不能写
    empty代表空闲资源量
    full代表已经装入了的量

信号量临界区保护

信号量必须要正确,不然肯定会出错,乱套
下图的例子会导致信号量错误
在这里插入图片描述
在这里插入图片描述
是竞争条件,不是编程错误,而是共享数据没有保护造成的竞争错误,你也争我也争,不该争的时候修改了它而导致的错误

  • 解决竞争条件

在这里插入图片描述

  • 引入临界区在这里插入图片描述
    那一段代码指的是修改empty的那段代码,p1进入p1的那段代码后,p2不能进入p2的那一段代码
    那一段代码就是临界区
    读写信号量的代码一定是临界区
    在这里插入图片描述
    所以要想进程能够正确的同步,就得保护它的临界区,保护临界区的核心就是进入区和退出区两段代码,原则是互斥
    除了互斥还包括下面两段点在这里插入图片描述
    在这里插入图片描述
    对于进程P0:turn=0才可进入,turn!=0就空转
    对于进程P1:turn=1才可进入,turn!=1就空转
    上图代码实现了互斥:
    p0进入时turn=0,p1不可进入,p0进完后,置turn为1,p1方可进入,p1进入是道理相同
    但是未实现有空让进:
    p0进完之后置turn=1,但此时p1不需要进入,所以空闲着,此时p0还想进入,因为turn被置位1了,所以没法进入,有空也不能进入
    在这里插入图片描述
    满足了互斥条件:
    p0想进入的时候打标记,令flag[0]=true,然后检查p1是否也进入了,如果flag[1]=true说明p1打了标记进入了,那么p0就只能等着,
    p0进完之后令flag[0]=0去掉标记
    所以满足了互斥
    但是还是不满足有空让进的条件:
    当p0想进的时候令flag[0]=true,此时调度到了p1,p1也想进,令flag[1]=true,此时p0,p1都打了标记,有空闲,但是谁都不能进去,
    在这里插入图片描述
    在这里插入图片描述
    满足互斥:
    如果p0进入了,说明flag[0]=true,flag[1]=false或turn=0,
    flag[0]=true或turn=0使p1进不去,
    也就是如果p0,p1都进去了,那么turn就会既等于0也等于1,显然矛盾
    所以满足了互斥
    满足有空让进:
    如果两个都不进,就肯定有个flag=false,有一个flag=false就会有一个进程不自转,进入
    满足有限等待:
    如果p0请求进入flag[0]=true,后面的p1不可能一直进入,因为p1执行一次,turn就会等于0,p1就会自转
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    上面的面包店方法是软件方法,太复杂了
    引入硬件方法
    在这里插入图片描述
    只有中断才会引起调度,所以阻止调度就可以关中断
    cli关中断,sti开中断
    上述方法在多核时不好使,因为你只关了1个CPU的中断,只控制了这个CPU不去调度,但是其他CPU还是会调度,你管不了其他CPU
    单CPU可以使用这个方法
    在这里插入图片描述如果x=false,令x=true,返回false,也就是判断没锁上的同时又加了锁,判断的结果是没锁上所以可以进入,判断的同时又加了锁,阻止其他进程进入

信号量的代码实现

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41386300/article/details/85227091