计算机操作系统生产者和消费者模型的简单介绍

同步互斥小口诀

  • 画图理解题目
  • 判断题目类型
  • 分析进程数目 填写进程模板
  • 补充基本代码(伪代码)
  • 补充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);
    }
    
}

猜你喜欢

转载自blog.csdn.net/CHYabc123456hh/article/details/112978296
今日推荐