信号量应用题

1. 生产者-消费者问题(互斥+同步)

生产者把消息放入缓冲区,消费者从中取出信息,二者互斥访问

semaphore mutex = 1;//互斥访问缓冲区,因为有多个缓冲区资源
semaphore empty = n;//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);//跟生产者进行同步,消费者——>生产者
  }
}
//桌上一盘子,爸爸放苹果,妈妈放橘子,儿子吃橘子,女儿吃苹果(爸妈互斥放盘,爸女同步、妈儿同步)
semaphore plate = 1,apple = 0,orange = 0;
dad() mom() son() daughter()

2. 读者-写者问题(互斥)

多个读者可以同时读、只允许一个写者写,写和读互斥

int count = 0;//公共计数器需要互斥访问
semaphore mutex = 1;//互斥访问计数器
semaphore rw = 1;//互斥进行读和写
semaphore w = 1;//互斥的提出申请资源
writerr(){//写者
    while(1){
    P(w);//互斥申请资源
    P(rw);//互斥读写
    //进行写操作
    V(rw);//互斥读写
    V(w);//允许其他程序申请资源
  }
}
reader(){//消费者
    while(1){
    P(w);//互斥申请资源
    P(mutex);//互斥访问count
    if(count==0) P(rw);//初始时,互斥读写
    count++;
    V(mutex);//互斥访问count
    V(w);//允许其他程序申请资源
    //读取数据
    P(mutex);//互斥访问count
    count--;
    if(count==0) V(rw);//释放读写权限
    V(mutex);//互斥访问count
  }
}

3. 哲学家进餐(互斥)

semaphore chopsticks[5]={1,1,1,1,1};//筷子资源
semaphore mutex = 1;//互斥申请筷子,本质上把取筷子弄成原子操作
Pi(){//i号哲学家进程
    while(1){
    P(mutex);//互斥申请资源
    P(chopsticks[i]);//取左边筷子
    P(chopsticks[(i+1)%5]);//取右边筷子
    V(mutex);//互斥申请资源
    //吃
    V(chopsticks[i]);//放回左边筷子
    V(chopsticks[(i+1)%5]);//放回右边筷子
  }
}

4. 吸烟者问题(同步)

int num = 0;//递增判断分配资源类型
semaphore offer1 = 0,offer2 = 0,offer3 = 0;//用于生产者->消费者同步
semaphore finish=0;//用于消费者->生产者同步

5. 读取奇偶(同步+互斥)

一进程随机产生数放入缓冲区,另两进程分别读取奇数偶数

semaphore mutex = 1;//互斥访问缓冲区
semaphore empty = N;//空闲区n个资源
semaphore odd=0,even=0;//用于奇数、偶数进程同步
P1(){//生产者
    while(1){
        x = preoduce();//生成一个数
        P(empty);//消耗资源
        P(mutex);//互斥访问缓冲区
        //数据x放入缓冲区
        V(mutex);//互斥访问缓冲区
        if(x%2==0) V(even);//同步偶数进程
        else V(odd);//同步奇数数进程
        P(mutex);//互斥访问门
        //出门
        V(mutex);//互斥访问门
        V(empty);//释放资源
  }
}
P2(){//消费奇数
    while(1){
        P(odd);//消耗奇数
        P(mutex);//互斥访问
        //从缓冲区得到奇数
        V(mutex);//互斥访问
        V(empty);//释放资源
        //给奇数计数
  }
}
P3(){//消费偶数
    while(1){
        P(even);//消耗奇数
        P(mutex);//互斥访问
        //从缓冲区得到偶数
        V(mutex);//互斥访问
        V(empty);//释放资源
        //给偶数计数
  }
}

6. A类B类产品(互斥)

每次只能放入一种,A-B<M,B-A<N

semaphore mutex = 1;//互斥访问仓库
semaphore Sa = M-1,Sb = N-1;//对AB资源在某种限度内的互斥访问,可知两者的资源上限是相互制约的
访问一次A类资源,同时要释放B类资源,同理B类也是,实现一定弹性的互斥访问

7. 面包取号叫号(互斥访问公共变量)

int i=0,j=0;//取号数和叫号数
semaphore mutex_i=0,mutex_j=0;//互斥访问公共变量

8. 参观博物馆(互斥)

博物馆可容纳500人,仅有一个出入口

semaphore mutex = 1;//互斥访问门
semaphore capacity = 500;//空闲资源数
Pi(){
    while(1){
        P(empty);//消耗资源
        P(mutex);//互斥访问门
        //进门
        V(mutex);//互斥访问门
        //参观
        P(mutex);//互斥访问门
        //出门
        V(mutex);//互斥访问门
        V(empty);//释放资源
  }
}

9. 生产车间和装配车间

两个生产车间生产A、B类零件,放到容量为10的两个货架上,装配工人每次取A、B零件组装

semaphore  empty1=10,empty2=10;//容量大小
semaphore full1=0,full2=0;//资源数量
semaphore mutex1 = 1,mutex2 = 1;//互斥访问缓冲区货架

10. 取水饮水(同步+互斥)

小和尚给老和尚取水,取水互斥,存水互斥,水缸容量10,水桶3个

semaphore well=1;//互斥访问水井
semaphore vat = 1;//互斥访问水桶
semaphore empty = 10;//水缸容量
semaphore full = 0;//水缸水量
semaphore  pail = 3;//水桶个数

11. 合作计算打印(同步)

semaphore s1=1,s2=0,s3=0;//实现进程的同步
semaphore sb=0,sy=0,sz=0;//判断对应数是否已经输入,用于同步

12. 银行取号叫号

银行有十个空位,互斥访问取号机,等待叫号

semaphore empty=10;//空位数量为10
semaphore full=0;//顾客初始为0
semaphore mutex = 1;//互斥访问取号机
semaphore service = 0;//用于营业员——>顾客叫号同步
P1(){//顾客
    while(1){
        P(empty);//等待消耗空位
        P(mutex);//互斥使用取号机
        //从取号机取号
        V(mutex);//互斥使用取号机
        V(full);//新增等待客户
        P(service);//等待叫号
  }
}

P2(){//营业员
    while(1){
        P(full);//等待客户
        V(service);//叫号
        V(empty);//释放座位
  }
}

13. 交通管制

不允许异向行驶,允许同方向多辆车行驶

int countSN=0,countNS=0;//记录两个方向车辆数量
semaphore mutexSN=1,mutexNS=1;//互斥访问公共变量
semaphore mutex = 1;//互斥访问桥

14. 自行车生产线(同步)

生产线上有N个箱子,工人1加工一个车架,工人2加工一个车轮,工人3取一个车架两个车轮组装

semaphore empty = N;//空闲位置
semaphore wheel = 0;//车轮数用于同步
semaphore frame = 0;//车架数用于同步
semaphore s1 = N-1;//车轮最大数量,防死锁
semaphore s2 = N-2;//车架最大数量,防死锁

15. 理发师(同步)

一把理发椅和n把供等待椅子,没有客户理发师在理发椅睡觉,没有椅子客户不等待

int chairs = n;//椅子数
int waiting = 0;//等待数
semaphore customers = 0;//客户——>理发师同步,唤醒理发师
semephore barbers = 0;//理发师——>客户同步,理发师准备剃头
semephore mutex = 1;//互斥访问公共变量,即互斥查看椅子状态

16. 电影院看影片

三部影片循环播放

semaphore s =1;//互斥看电影
semaphore s1=1,s2=1,s3=1;//互斥访问公共变量
int count1 = 0,count2=0,count3=0;//公共变量记录看当前电影人数

17. 安全岛错车

安全岛允许两辆车停留错车(两个方向各一辆),L路段和K路段只允许一辆车通过(在互斥变量的访问和释放上体现方向性即可)

semaphore T2N = 1, N2T = 1;//两个方向行驶互斥
semaphore L = 1, K =1;//两个路段的互斥

18. 消费者连续取

semaphore mutex1=1,mutex2=1;//互斥对缓冲区进行存取,以及使连续取成为原子操作,这里用for循环
semaphore empty = n;/空闲资源
semaphore full = 0;//资源

19. 邮箱辩论

A邮箱容量M,B邮箱容量N,初始A邮箱x个邮件,B邮箱y个邮件

semaphore full_a = x,full_b = y;//初始邮件数
semaphore empty_a = M-x, empty_b = N-y;//还可以存放的邮件数
semaphore mutex1=1,mutex2=1;//互斥访问邮箱A,互斥访问邮箱B
A(){
    while(1){
       P(full_a);
       P(mutex1);
       //取邮件
       V(mutex1);
       V(empty_a);
       //回答问题
       P(empty_b);
       P(mutex2);
       //放入邮件
       V(mutex2);
       V(full_b);
  }
}
//另一程序基本一致

20. 三线程(互斥)

三个全局变量x、y、z,线程1访问x、y(只读),线程2访问y,z(只读),线程3访问z,y(读写)

semaphore mutex1 = 1;//用于y变量读1和写3的互斥
semaphore mutex2 = 1;//用于y变量读2和写3的互斥
semaphore mutex3 = 1;//用于z变量的互斥读写

21. 哲学家进餐(加碗并优化)

m个碗和n个哲学家

semaphore chopsticks[n];
for(int i=0;i<n;i++) chopsticks[i]=1;//初始化进行互斥使用
semaphore bowl = min(n-1,m);//防止死锁,最多只有bowl个人进行申请资源
Pi(){//i号哲学家进程
    while(1){
    P(bowl);//互斥申请资源
    P(chopsticks[i]);//取左边筷子
    P(chopsticks[(i+1)%n]);//取右边筷子
    //吃
    V(chopsticks[i]);//放回左边筷子
    V(chopsticks[(i+1)%n]);//放回右边筷子
    V(bowl);//释放资源
  }
}

22. 操作同步

A、B、C、D、E五个操作,C在A、B完成之后,E在C、D完成之后

semaphore SAC=0,SBC=0,SCE=0,SDE=0;//四个同步关系
A(){V(SAC)}
B(){V(SBC)}
C(){P(SAC)P(SBC)V(SCE)}
D(){V(SDE)}
E(){P(SCE)P(SDE)}
posted @ 2022-08-28 01:52  失控D大白兔  阅读(40)  评论(0编辑  收藏  举报