目录
提示:以下是关于信号量使用的总结
一、信号量的作用
1.1 实现互斥关系
1.2 实现同步关系
二、经典同步问题
1. 关系分析:找出题目中描述的各个进程,分析它们之间的同步、互斥关系
2. 整理思路:根据各进程的操作流程确定P、V操作的大致顺序
3. 设置信号量:并根据题目条件确定信号量初值。(互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少)
2.1 生产者-消费者问题(1对1)
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据)生产者、消费者共享一个初始为空、大小为n的缓冲区。
semaphore mutex = 1; //互斥信号量,实现对缓冲区的互斥访问
semaphore empty = n; //同步信号量,表示空闲缓冲区的数量
semaphore full = 0; //同步信号量,表示产品的数量,也即非空缓冲区的数量
producer(){
while(1){
生产一个产品;
P(empty);
P(mutex);
把产品放入缓冲区;
V(mutex);
V(full);
}
}
consumer(){
while(1){
P(full);
P(mutex);
从缓冲区取出一个产品;
V(mutex);
V(empty);
使用产品;
}
}
(1)复杂的同步关系:
生产者和消费者具有同步关系,但是不是简单的同步关系,生产者和消费者具有双向的同步关系;
因为生产者和消费者是否能工作的前提变为缓冲区空闲块的数量,所以需要两个同步信号量完成;
empty ?= 0 来表明是否存在空闲缓冲区,是生产者的同步关系;
full ?= 0 来表明是否存在非空缓冲区,是消费者的同步关系
(2)同步关系和互斥关系的顺序
互斥和同步信号量的前后顺序无法改变,因为我们应当先判断是否有进入的条件,再争夺缓冲区的互斥使用权;
但是对于互斥和同步是释放顺序是任意的;
(3)特殊情况:缓冲区为1时
(1)当缓冲区为1时,即使不设置专门的互斥变量mutex,也不会出现多个进程同时访问的现象;
只有 empty = 1,full = 0;或者 empty = 0, full = 1;两种情况
一旦生产者或者消费者拿到进入的条件,
此时 empty = 0,full = 0;或者 empty = 0, full = 0;两种情况
由于缓冲区为1,则导致任何时候,只会有一个进程进入,所以使得mutex可以省略;
semaphore empty = n; //同步信号量,表示空闲缓冲区的数量
semaphore full = 0; //同步信号量,表示产品的数量,也即非空缓冲区的数量
producer(){
while(1){
生产一个产品;
P(empty);
把产品放入缓冲区;
V(full);
}
}
consumer(){
while(1){
P(full);
从缓冲区取出一个产品;
V(empt