一、生产者-消费者问题
生产者进程 缓冲区 消费者进程
1、缓冲区没满(V):(P)生产者生产 信号量1
2、缓冲区不空(V):(P)消费者取走数据 信号量2
3、缓冲区必须互斥访问
信号量1:产品数量,初始为0
信号量2:空闲缓冲区,初始为n
semaphore full=0;
semaphore empty=n;
semaphore mutex=1; //互斥信号量
producer(){
while(1){
生产一个产品;
P(empty);//消耗一个空闲缓冲区
P(mitex);
把产品放入缓冲区;
V(mutex);
V(full);
}
}
consumer(){
while(1){
P(full);//消耗一个产品
P(mutex);
从缓冲区取出一个产品;
V(mutex);
V(empty);//增加 一个空闲缓冲区
使用产品;
}
}
顺序问题:P(互斥)要在P(同步)之前,V随意
二、多生产者-多消费者
1、盘子空:父、母放 信号量plate=1
2、有橘子:儿子拿 信号量orange=0
3、有苹果:女儿拿 信号量apple=0
4、对盘子互斥访问 信号量mutex=1
semaphore mutex=1;
semaphore apple=0;
semaphore orange=0;
semaphore plate=1;//盘子里可以放多少
dad(){
while(1){
准备一个苹果;
P(plate);
P(mutex);
把苹果放入盘子;
V(apple);
V(mutex);
}
}
mom(){
while(1){
准备一个橘子;
P(plate);
P(mutex);
把橘子放入盘子;
V(orange);
V(mutex);
}
}
daughter(){
while(1){
拿走一个苹果;
P(apple);
P(mutex);
吃掉苹果;
V(plate);
V(mutex);
}
}
son(){
while(1){
拿走一个橘子;
P(orange);
P(mutex);
吃掉橘子;
V(plate);
V(mutex);
}
}
三、吸烟者问题
1、供应者提供一组材料:吸烟者吸烟 信号量1offer1=0 20ffer2=0 30ffer3=0
2、吸烟者发出已吸烟信号:供应者生产材料 信号量4finish=0
3、对桌子容量互斥访问 信号量mutex=1
semaphore offer1=0;//组合一数量
semaphore offer2=0;
semaphore offer3=0;
semaphore finish=0;//吸烟未完成
int i=0;
provider(){
while(1){
if(i==0){
将组合一放到桌子上;
V(offer1);
}
else if(i==1){
将组合二放到桌上;
v(offer2);
}
else if(i==2){
将组合三放到桌上;
v(offer3);
}
i=(i+1)%3;
P(finish);
}
}
smoker1(){
while(1){
P(offer1);
拿走组合一
V(finish);
}
}
smoker2(){
while(1){
P(offer2);
拿走组合二
V(finish);
}
}
smoker3(){
while(1){
P(offer3);
拿走组合三
V(finish);
}
}
四、读者-写者问题
读者 文件 写者
读者 写者
1、文件无访问:写者写进程
2、写者写完:其他访问
3、写者对文件互斥访问,写者与读者互斥
semaphore rw=1;//互斥
int count=0;//读文件进程数
semaphore mutex;//保证对count互斥访问
semaphore w=1;//保证写优先
writer(){
while(1){
P(rw);//写之前加锁
写操作;
V(rw);//写完解锁
}
}
reader(){
while(1){
P(w);
P(mutex);//各进程互斥访问count
if(count==0)
P(rw);//第一个进程读之前加锁
count++;//访问 的进程数+1
V(mutex);
V(w);
读操作;
P(mutex);//互斥访问count
count--;//访问进程数-1
if(count==0)
V(rw);//最后一个进程读完解锁
V(mutex);
}
}
五、哲学家进餐问题
1、左右有筷子:进餐
2、饥饿:进餐
3、对筷子互斥访问
4、避免死锁
ps:哲学家编号i=0:4,与哲学家左手边筷子编号相同,右手边筷子(i+1)%5
semaphore chopstick[5]={1,1,1,1,1};//对筷子互斥信号量
semaphore mutex=1;
Pi(){
while(1){
P(mutex);
P(chopstick[1]);
P(chopstick[1+1]);
V(mutex);
吃饭;
V(chopstick[1]);
V(chopstick[1+1]);
思考;
}
}