为啥要引入信号量机制,关于实现进程互斥我们有四种软件实现方法,三种硬件实现方法,但是要么就是不能让上锁和检查一气呵成出现问题,要么就是上述所有方法都有的一个通病:不能实现让权等待。那么,就是信号量机制诞生的意义啦。
信号量:一个变量(可以是一个整数,也可以是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量。
用户进程可以通过使用操作系统提供的一对原语来对信号量操作,从而很方便的实现进程互斥,进程同步。
划重点:一对原语:P,V操作=>P(S),V(S),S为调用时传入的参数,是信号量;其中P,V分别可表示为wait和signal
信号量机制–整型信号量用一个整数型变量作为信号量,这里这个整型信号量只能用于三种情况,初始化,P操作,V操作
wait实现的底层原理
1 | int S = 1; //初始化 |
signal实现的底层原理
1 | int S = 1; |
例如:这里有一个进程P0
···
P(s); //进入区,申请资源
//临界区,访问资源
V(s); //退出区,释放资源
···
敲重点!!!整型信号量的缺陷就是不满足让权等待
信号量机制–记录型信号量先来看看原理
1 | //记录型信号量的定义 |
这个过程要是不理解就写出四个进程,给两个资源自己比划比划,但是要强调一下,不论是P操作还是V操作,不论满不满足资源够用,都要先对value操作。这样就避免了违反让权等待。
用信号量实现进程互斥1 分析问题,找出临界区
2 设置互斥信号量,初值为1(因为临界区只允许一个)
3 进临界区之前做P操作
4 进临界区之后做V操作
举个栗子
1 | semaphore s = 0; |
问题来了,什么是同步,那就记好了,同步就是你想让他有顺序,比如谁必须在谁之前执行,注意理解下面第3,4步
1 分析问题,找出哪里需要实现”一前一后”的同步关系(比如代码4必须在代码2后执行)
2 设置同步信号量,初始值为0
3 在前操作之后执行V操作
4 在后操作之前执行P操作
举个栗子
1 | semaphore s = 0; |
1 分析问题,画出前驱图,把一堆钱去关系都看成一个同步问题
2 为每一对前驱关系设置同步信号量,初值为0
3 在前操作之后执行V操作
4 在后操作之前执行P操作
举个栗子
如上图就是一个前驱图,说白了就是必须在谁谁谁完成之后,谁谁谁才能运行,比如S1完了,S2,S3才行;S2完了,S4,S5才行;S4,S5,S3完了,S6才行。而每一条箭头连接的两个进程就是同步关系,依次信号量都是0,遵循同步的规则
1 |
|
因此只要把图画出来就会变得非常简单