• 操作系统:2.3.5经典同步问题(1)——生产者消费者问题,多生产者多消费者问题


    1. 生产者——消费者问题

    问题描述:一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或一个消费者从中取出消息。

    问题分析

    1. 分析关系

    1. 同步关系:在这里插入图片描述

    2. 互斥关系:
      在这里插入图片描述

    2. 整理思路

    1. 同步关系的P、V操作:
      在这里插入图片描述
    2. 互斥关系的P、V操作:

    3. 信号量初值设置

    1. 同步信号量:
      信号量full用于记录当前缓冲池中的“满”缓冲区数,初值为0
      信号量empty用于记录当前缓冲池中的“空”缓冲区数,初值为n
    2. 互斥信号量:
      信号量mutex作为互斥信号量,用于控制互斥访问缓冲池,互斥信号量初值为1;

    代码

    semaphore mutex=l;					//临界区互斥信号量
    semaphore einpty=n;					//空闲缓冲区
    semaphore full=0;					//缓冲区初始化为空
    
    producer(){							//生产者进程
    	while(1){
    		produce an item in nextp;	//生产数据
    		P (empty);(要用什么,P—下)	//获取空缓冲区单元
    		P (mutex);(互斥夹紧)			//进入临界区
    		add nextp to buffer;(行为)	//将数据放入缓冲区
    		V (mutex);(互斥夹紧)			//离开临界区,释放互斥信号量
    		V(full);(提供什么,V—下)		//满缓冲区数加1
    	}
    }
    
    
    consumer(){							//消费者进程
    	while (1){
    		P(full);					//获取满缓冲区单元
    		P(mutex);					//进入临界区
    		remove an item from buffer;	//从缓冲区中取出数据
    		V(mutex);					//离开临界区,释放互斥信号量
    		V(empty);					//空缓冲区数加1
    		consume the item;			//消费数据
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    同步和互斥的顺序能否调换顺序?

    在这里插入图片描述
    类比:
    在这里插入图片描述

    2. 多生产者——消费者问题

    问题描述:桌子上有一个盘子,每次只能向其中放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈才可向盘子中放一个水果;仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取岀。

    问题分析

    1. 分析关系

    1. 同步关系
      在这里插入图片描述
    2. 互斥关系
      在这里插入图片描述
      这里有4个进程,实际上可抽象为两个生产者和两个消费者被连接到大小为1的缓冲区上。

    2. 信号量设置

    1. 同步信号量
      信号量apple表示盘子中是否有苹果,初值为0表示盘子为空,不许取,apple=1表示可以取。
      信号量orange表示盘子中是否有橘子,初值为0表示盘子为空,不许取,orange=1表示可以取。
    2. 互斥信号量
      信号量plate,表示是否允许向盘子放入水果,初值为1表示允许放入,且只允许放入一个。

    代码

    加互斥信号量的代码(推荐)

    semaphore plate=1,apple=0,orange=0;
    
    dad(){									//父亲进程
    	while(1){
    		prepare an apple;
    		P(plate);						//互斥向盘中取、放水果
    	P(mutex); 
    		put the apple on the plate;		//向盘中放苹果
    	V(mutex);
    		V(apple);						//允许取苹果
    	}
    }
    
    mom(){									//母亲进程
    	while(1){
    		prepare an orange;
    		P(plate);						//互斥向盘中取、放水果
    	P(mutex);
    		put the orange on the plate;	//向盘中放橘子
    	V(mutex);
    		V(orange);						//允许取橘子
    	}
    }
    
    
    son () {								//儿子进程
    	while(1){
    		P (orange);						//互斥向盘中取橘子
    	P(mutex);
    		take an orange from the plate;
    	V(mutex);
    		V (plate);						//允许向盘中取、放水果
    		eat the orange;
    	}
    }
    
    daughter (){							//女儿进程
    	while (1){
    		P (apple);						//互斥向盘中取苹果
    	P(mutex);
    		take an apple from the plate;
    	V(mutex);
    		V (plate);						//允许向盘中取、放水果
    		eat the apple;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    不加上互斥信号量的代码

    semaphore plate=1,apple=0,orange=0;
    
    dad(){									//父亲进程
    	while(1){
    		prepare an apple;
    		P(plate);						//互斥向盘中取、放水果
    		put the apple on the plate;		//向盘中放苹果
    		V(apple);						//允许取苹果
    	}
    }
    
    mom(){									//母亲进程
    	while(1){
    		prepare an orange;
    		P(plate);						//互斥向盘中取、放水果
    		put the orange on the plate;	//向盘中放橘子
    		V(orange);						//允许取橘子
    	}
    }
    
    
    son () {								//儿子进程
    	while(1){
    		P (orange);						//互斥向盘中取橘子
    		take an orange from the plate;
    		V (plate);						//允许向盘中取、放水果
    		eat the orange;
    	}
    }
    
    daughter (){							//女儿进程
    	while (1){
    		P (apple);						//互斥向盘中取苹果
    		take an apple from the plate;
    		V (plate);						//允许向盘中取、放水果
    		eat the apple;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述

    参考资料

    《王道:23操作系统考研复习指导》

  • 相关阅读:
    HarmonyOS 权限 介绍
    工具篇之Axure RP 10的使用
    【附源码】Python计算机毕业设计汽车租赁系统
    Docker入门之安装Tomcat
    当Web3的人们高喊数据工具优化,如何用UGC引领数据服务趋势?
    Go语言基础-基础语法
    Python逆向爬虫之pyquery,非常详细
    ResNet论文及实现
    二叉搜索树
    LeetCode 2578. 最小和分割【贪心,排序+奇偶分组】1350
  • 原文地址:https://blog.csdn.net/weixin_46629453/article/details/126306388