操作系统生产者和消费者python3实现
来源:互联网 发布:linux ant下载安装 编辑:程序博客网 时间:2024/06/07 03:15
【一】生产者和消费者实现原理:
简易思维导图
1.问题背景:避免进程之间出现临界资源的互斥访问的死锁现象
2.解决方式:记录型信号量机制
3.具体细节:
- mutex:互斥信号量,初始值是1
- empty:判空信号量
- full:判满信号量
- array[n]:缓冲池存放产品
4.实现好处: 解决死锁
【二】实现细节设计:
缓存池:循环队列 in,out标记队头和队尾
利用in,out指针实现加减操作放入拿出产品
in:指向当前最后产品的存储空间(队位,放入)(rear)
out:指向最早放入产品存储空间(队头,拿取)(head)
具体生产者:生产者生产产品,in=(in+1)%n记录更新位置
具体消费者:消费者拿取产品,out=(out+1)%n记录更新位置互斥信号量:初始值为1,保证临界资源的互斥性
3.代码构建:
对象 消费者和生产者 调用
循环队列 (阻塞队列)缓冲池
4.代码实现:
①基本队列内容编写
class Queue(object):# 定义队列类 def __init__(self,size): self.size = size #定义队列长度 self.queue = []#存储队列 列表 #返回对象的字符串表达式 方便调试 def __str__(self): return str(self.queue)#什么含义 #初始化队列 #def init(self): #入队 def inQueue(self,n): if self.isFull(): return -1 self.queue.append(n)#列表末尾添加新的对象 #出队 def outQueue(self): if self.isEmpty(): return -1 firstElement = self.queue[0] #删除队头元素 self.queue.remove(firstElement) #删除队操作 return firstElement #删除某元素 def delete(self,n,m): self.queue[n] = m #插入某元素 def inPut(self,n,m):#n代表列表当前的第n位元素 m代表传入的值 self.queue[n] = m #获取当前长度 def getSize(self): return len(self.queue) #判空 def isEmpty(self): if len(self.queue)==0: return True return False #判满 def isFull(self): if len(self.queue) == self.size: return True return False#if __name__ == '__main__':#如何使用?queueTest = Queue(10)for i in range(10): queueTest.inQueue(i)print('列表元素',queueTest)print('列表长度',queueTest.getSize())print('判空',queueTest.isEmpty())print('判满',queueTest.isFull())queueTest.inPut(1,20)#list【0】 = 2queueTest.outQueue()#出队print('当前列表',queueTest)结果:列表元素 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]列表长度 10判空 False判满 True当前列表 [20, 2, 3, 4, 5, 6, 7, 8, 9]
②生产者消费者代码具体实现
#全局变量实现头尾指针动态指向内容ii = 0head = 0rear = 0mutex = 1#互斥信号量 初始为1标志当前队列有无被占用flag =1 #标志初始化#消费者class Customer(): def __init__(self): print('>>>消费者请求访问仓库') def opreate(self,customer): if flag ==1: #如何使队列只能创建一个对象 全局 customer.init()#列表越界很可能就是列表越界 global mutex # 创建队列对象 以便队列操作 if mutex == -1: return print('>>>缓冲区当前正有人操作,消费者不能操作') else: mutex = mutex - 1 if (customer.isEmpty())== True: print('>>>当前缓冲区为空,消费者不能取用产品') if input('是否调用生产者提供补给(输入1-YES|0-NO) ')=='1': print('>>>调用生产者') mutex = mutex+1 product=Producer() product.opreate(customer) else: mutex = mutex + 1 return print('>>>拒绝提醒,消费者继续等待') else: customer.outPut() #其中包含head的操作 print('消费者取用产品完毕,当前产品队列从', head, '到', rear, '处依然存有产品','缓存队列',customer) mutex =mutex+1 #操作完毕互斥量恢复class Producer(): def __init__(self): print('>>>生产者请求访问缓存区') def opreate(self,producer): if flag == 1: producer.init() #重复初始化 傻瓜式不影响 print(producer) global mutex if mutex == -1: return print('>>>缓冲区当前繁忙,生产者不能进行操作') else: mutex = mutex-1 if producer.isFully() == True: print('>>>缓冲区为满,生产者不能放入产品') if input('是否调用消费者进行消耗(输入1-YES|0-NO) ') == 1: print('>>>调用消费者') mutex = mutex+1 customer=Customer() customer.operate(CirQueue()) else: mutex = mutex + 1 return print('>>>拒绝提醒,生产者继续等待') else: producer.inPut('产品') mutex = mutex + 1 print('>>>生产者生产产品完毕,当前产品队列从', head, '到', rear-1, '处依然存有产品','缓存队列',producer)class CirQueue():#循环队列队头取元素 队末尾插入元素 #可加可不加object 报错ndentationError: expected an indented block 为什么? def __init__(self): self.size =11#队列固定长度 self.Queue=[]#队列以列表形式定义 global head,rear,i head = 0#存储头队列元素 用于消费者删除 rear = 0#存储尾队列元素 用于生产者放入 def __str__(self): return str(self.Queue) def init(self):#初始化 头尾标志依旧指向首位 self.Queue=[0,0,0,0,0,0,0,0,0,0,0]#傻瓜式初始化 global flag flag = 0 # 判空 def isEmpty(self): j = 0 # print('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', j) count = 0 while j != 10: # 将10个元素全部遍历 if self.Queue[j] == 0: count = count + 1 # 记录元素为空的元素个数 j = j + 1 if count == 10: return True return False # 判满 def isFully(self): j = 0 # print('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', j) count = 0 while j != 10: # 将10个元素全部遍历 if self.Queue[j] == 0: count = count + 1 # 记录元素为空的元素个数 j = j + 1 if count == 0: return True return False #队尾插入元素 def inPut(self,n):#n代表插入的元素 global rear print(self.Queue) #print('aaaaaaaaaaaaaaa', rear) #print('aaaaaaaaaaaaaaa', rear) if rear == 10:#判满操作不符合循环 return print('队列已满') else: i= rear while self.Queue[i]!=0: i=i+1 if i==11:#判断 空 元素值全为0 rear = 0 #self.rear=0#正常队尾插入元素操作 elif i>0|i<10:#中间元素不为空 rear=i elif i==10:#空 return print( '队列已满') self.Queue[rear]=n #插入元素n rear = rear+1 #队头取元素 def outPut(self): global head j=0 count =0 while j!=10:#将10个元素全部遍历 if self.Queue[j] ==0: count = count+1#记录元素为空的元素个数 j =j+1 if count == 10:#列表里为空 return print('列表为空不能取元素') else: i =head while self.Queue[i]!=0: i=i+1 head = i self.Queue[head] = 0 # 赋值0 ---清除元素操作"""测试内容:test = CirQueue()#满队列不能放入实现test.init()#初始化 11个0print(test)for i in range(10):#操作放满缓冲区10个元素 test.inPut('产品')print(test)print('aaaaaaaaaaaaaaa',rear)test.inPut(1)#期待此操作过后出现 报满提示#空队列不能拿出test.init()test.outPut()#期待空元素 报空提示print(test)"""#队列初始化test = CirQueue()test.init()#初始化 11个0print(test)#消费者访问缓冲区拿元素cus0 = Customer()cus0.opreate(test)#期待结果是 消费者判断当前缓存队列为空 调用生产者生产 放入一个产品print('ssssssssssssssssssssssss',test)pro0 = Producer()pro0.opreate(test)print(test)pro1 = Producer()pro1.opreate(test)print(test)"""结果:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>>>消费者请求访问仓库>>>当前缓冲区为空,消费者不能取用产品是否调用生产者提供补给(输入1-YES|0-NO) 1>>>调用生产者>>>生产者请求访问缓存区[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0][0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>>>生产者生产产品完毕,当前产品队列从 0 到 0 处依然存有产品 缓存队列 ['产品', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]ssssssssssssssssssssssss ['产品', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>>>生产者请求访问缓存区['产品', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]['产品', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>>>生产者生产产品完毕,当前产品队列从 0 到 1 处依然存有产品 缓存队列 ['产品', '产品', 0, 0, 0, 0, 0, 0, 0, 0, 0]['产品', '产品', 0, 0, 0, 0, 0, 0, 0, 0, 0]>>>生产者请求访问缓存区['产品', '产品', 0, 0, 0, 0, 0, 0, 0, 0, 0]['产品', '产品', 0, 0, 0, 0, 0, 0, 0, 0, 0]>>>生产者生产产品完毕,当前产品队列从 0 到 2 处依然存有产品 缓存队列 ['产品', '产品', '产品', 0, 0, 0, 0, 0, 0, 0, 0]['产品', '产品', '产品', 0, 0, 0, 0, 0, 0, 0, 0]Process finished with exit code""""""测试内容:#放入10个产品test = CirQueue()test.init()for i in range(10): test.inPut('产品') print(test)"""
阅读全文
0 0
- 操作系统生产者和消费者python3实现
- 操作系统 使用C语言实现生产者和消费者问题
- 【操作系统】【学习】生产者和消费者问题
- 生产者和消费者问题c++(操作系统)
- Java 实现生产者和消费者
- 生产者和消费者Java实现
- ActivityMQ实现生产者和消费者
- 生产者和消费者线程实现
- python3用消费者和生产者模型,实现视频流读取播放
- 操作系统:生产者-消费者问题
- 操作系统 生产者消费者问题
- 操作系统:生产者消费者问题
- Python3之线程Queue实现生产者消费者模型
- 操作系统:使用临界区和互斥量两种方法实现简单生产者与消费者问题
- java中notify和wait实现操作系统pv操作(单一生产者消费者)
- 生产者-消费者问题(操作系统)原理与实现
- 用java实现生产者和消费者问题
- 生产者和消费者实现(Java)
- SpringCloud(第 022 篇)Zuul 网关微服务的 regexmapper 属性测试, 类似测试 zuul 的自定义路径规则一样
- ReentrantLock类源码解析
- ..\OBJ\LCD.axf: error: L6047U: The size of this image (34984 bytes) exceeds,KEIL5破解方法
- java中的值传递,引用传递,==,equal,random
- 基础练习 BASIC-16 分解质因数
- 操作系统生产者和消费者python3实现
- Java中static和final的区别
- redis学习笔记(三)
- Python3学习笔记1-3
- webservice学习总结(1)基础知识
- 五.java多线程之线程同步
- BufferedReader reader= new BufferedReader(new InputStreamReader(System.in))解读
- HDU1847:Good Luck in CET-4 Everybody!(SG博弈)
- 5.MongoDB索引