同步互斥小口诀
- 画图理解题目
- 判断题目类型
- 分析进程数目 填写进程模板
- 补充基本代码(伪代码)
- 补充PV代码
- 检查调整代码
注意事项
- 代码是一步一步写出来的,代码是反复调整写出来的
- 60%是生产者和消费者模型
- 30%是读者和写者的模型
生产者和消费者
例子1
- 妈妈每次放放一个苹果到桌子上,孩子每次从桌子上取一个苹果。取苹果和放苹果不可以同时进行,而且桌子上最多只能放10个苹果,请使用pv代码实现同步互斥
- 箭头 代表生产的含义,数目代表生产的数量
- 特征:1,存在一个容器,具有容量的限制;2,具有生产行为和消费行为,生产行为增加容量,消费行为减少容量
- 分析:生产者:需要考虑容器的容量,考虑的是剩余空间;消费者:需要考虑已占用空间
- 进程的数目:母亲 和 孩子两个进程
- 补充基本代码 取一个苹果 和 放一个苹果
- 补充PV代码 full代表占用空间;empty代表已经占用的空间;p代表减;v代表加
- 使用P(s)和V(s)包住会改变容器容量的代码,也就是临界资源
- 代码
semaphore full = 0; //表示资源
semaphore empty = 10;//表示资源
semaphore s = 1; //表示互斥
孩子(){while(1){p(full);//是否有已占用空间,有则减少已占用空间,无则等待p(s);取一个苹果;v(s);v(empty);//增加剩余空间}
}妈妈(){while (1){p(empty);//是否有剩余空间,有则减少剩余空间,无则等待p(s);放一个苹果;v(s);v(full);//增加已占用空间}}
例子2
- 桌子上有一个盘子,每次只能放入一个水果,妈妈放入橘子,爸爸放入苹果,儿子吃橘子,女儿吃苹果。盘子为空,爸爸妈妈才可以放入水果,当盘子的水果和儿子或者女儿匹配的时候,儿子和女儿才可以拿水果
- 消费者(儿子) 关注橘子;消费者(女儿)关注苹果;生产者(妈妈)关注盘子空间;生产者(爸爸)关注盘子空间
- 四个进程
- mutex 和 plate的效果是等价的,因此,这里不加mutex也是可以的
- 代码
semaphore orange = 0;
semaphore apple = 0;
semaphore plate = 1;
semaphore mutex = 1;
妈妈(){while(1){p(plate);p(mutex);放橘子;v(mutex);v(orange);}
}爸爸(){while (1){p(plate);p(mutex);放苹果;v(mutex);v(apple);}}儿子(){while (1){p(orange);p(mutex);吃橘子;v(mutex);v(plate);}}女儿(){while (1){p(apple);p(mutex);吃苹果;v(mutex);v(plate);}}
例子3
- AB两个人通过信箱进行辩论,每个人都从自己的信箱取出对方的问题,将答案和新的问题组成一个邮件放入对方的信箱中,假设A的信箱可以装入M个邮件,B的信箱可以装入N个邮件,初始的时候,A信箱有X封邮件,B信箱有y封邮件,辩论者每次只取一封邮件,请使用PV操作实现,并解释信号量初值和含义
- 分析
- 生产者 A 关注 B的邮箱剩余空间
- 生产者 B 关注 A的邮箱剩余空间
- 消费者 A 关注 A的邮箱有多少封信件
- 消费者 B 关注 B的邮箱有多少封信件
- 代码
semaphore mutex_A = 1;
semaphore mutex_B = 1;
semaphore full_A = x;
semaphore empty_A = M - x;
semaphore full_B = y;
semaphore empty_B = N - y;
A(){while(1){p(full_A);p(mutex_A);从A的邮箱抽取信件;v(mutex_A);v(empty_A);p(empty_B);p(mutex_B);向B的邮箱投递信件;v(mutex_B);v(full_B);}
}B(){while (1){p(full_B);p(mutex_B);从B的邮箱抽取信件;v(mutex_B);v(empty_B);p(empty_A);p(mutex_A);向A的邮箱投递信件;p(mutex_A);p(full_A);}}
例子4
- 系统中有多个生产者和消费者,共享一个能存放1000件产品的环形缓冲区(初始为空)。当缓冲区没有满的时候,生产者可以放入生产的一个产品,否则等待,当缓冲区域不为空的时候,消费者进程可以取走一件商品,否则等待。要求一个消费者从缓冲区域连续取走10个产品之后,其他消费者才可以取走产品,请使用PV实现该流程并解释信号量的含义
- 生产者 j 剩余空间
- 消费者 i 剩余空间
- 消费者 m 物件数量
- 消费者 n 物件数量
- 代码
semaphore empty = 1000;
semaphore full = 0;
semaphore mutex = 1;
semaphore mutex_2 = 1;
生产者i(){while(1){p(empty);p(mutex);放一件物品;v(mutex);v(full);}
}生产者j(){while(1){p(empty);p(mutex);放一件物品;v(mutex);v(full);}
}消费者m(){while (1){p(mutex_2);for(int i = 0;i < 10;i++){p(full);p(mitex);取一件物品;v(mutex);v(empty);}v(mutex_2);}}消费者n(){while (1){p(mutex_2);for(int i = 0;i < 10;i++){p(full);p(mitex);取一件物品;v(mutex);v(empty);}v(mutex_2);}}