生产者与消费者模型
1、生产者与消费者模型
大家应该都有过去小吃摊吃东西的经历,商家的资源是有限的
商家是生产者,我们是消费者,
商家要考虑会不会浪费了,当产品数量少于10的时候就开始生产
只要有商品,消费者就可以消费,消费者要消费多少也由消费者确定
1.1 生产者与消费者
这里定义两个生产者(老板和老板娘),5个消费者
import threading
from time import sleep
products = 0
# 定义一个生产者类
class Productor(threading.Thread):
ix = [0] #生产者的编号
# 重写一个函数
def __init__(self):
# 使用父类初始化
super().__init__()
self.ix[0] += 1
self.setName('生产者'+str(self.ix[0]))
def run(self):
global products
while True:
if products<10:
#当产品数量少于10的时候就开始生产
products += 1
print('%s:库存不足10,我努力生产了一个产品,现在产品重量为%d'%(self.getName(),products))
else:
print('%s:库存充足,不需要继续生产,当前库存为:%d'%(self.getName(),products))
sleep(2)
# 定义一个消费者类
class Cousmter(threading.Thread):
ix = [0]
def __init__(self,ix=0):
super().__init__()
self.ix[0] += 1
self.setName('消费者'+str(self.ix))
def run(self):
global products
while True:
if products >0:
products -= 1
print('%s:我消费了1个产品,现在产品的数量为: %d'%(self.getName(),products))
else:
print('%s: 没有商品了,我不能消费了'%self.getName())
sleep(2)
if __name__ == '__main__':
for _ in range(2):
p = Productor()
p.start()
for _ in range(5):
c = Cousmter()
c.start()
运行一下这个程序
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为2
消费者[1]:我消费了1个产品,现在产品的数量为: 1
消费者[1]:我消费了1个产品,现在产品的数量为: 0
消费者[1]: 没有商品了,我不能消费了
消费者[2]: 没有商品了,我不能消费了
消费者[3]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为2
消费者[4]:我消费了1个产品,现在产品的数量为: 1
消费者[1]:我消费了1个产品,现在产品的数量为: 0
消费者[3]: 没有商品了,我不能消费了
消费者[1]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
消费者[2]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为2
消费者[4]:我消费了1个产品,现在产品的数量为: 1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
消费者[2]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
消费者[3]: 没有商品了,我不能消费了
消费者[1]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为2
消费者[1]:我消费了1个产品,现在产品的数量为: 1
消费者[3]:我消费了1个产品,现在产品的数量为: 0
消费者[3]: 没有商品了,我不能消费了
消费者[2]: 没有商品了,我不能消费了
消费者[1]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
现在造成什么情况呢,就是有人消费但是没达到自己的消费量,但是有人就没有消费过
怎么解决这种情况呢?
加互斥锁
1.2 互斥锁
import threading
from time import sleep
products = 0
# 创建一个互斥锁
lock = threading.Lock()
# 定义一个生产者类
class Productor(threading.Thread):
ix = [0] #生产者的编号
# 重写一个函数
def __init__(self):
# 使用父类初始化
super().__init__()
self.ix[0] += 1
self.setName('生产者'+str(self.ix[0]))
def run(self):
global products
while True:
# 加锁
if lock.acquire():
if products<10:
#当产品数量少于10的时候就开始生产
products += 1
print('%s:库存不足10,我努力生产了一个产品,现在产品重量为%d'%(self.getName(),products))
else:
print('%s:库存充足,不需要继续生产,当前库存为:%d'%(self.getName(),products))
#释放锁
lock.release()
sleep(2)
# 定义一个消费者类
class Cousmter(threading.Thread):
ix = [0]
def __init__(self,ix=0):
super().__init__()
self.ix[0] += 1
self.setName('消费者'+str(self.ix))
def run(self):
global products
while True:
# 加锁
if lock.acquire():
if products >0:
products -= 1
print('%s:我消费了1个产品,现在产品的数量为: %d'%(self.getName(),products))
else:
print('%s: 没有商品了,我不能消费了'%self.getName())
# 释放锁
lock.release()
sleep(2)
if __name__ == '__main__':
for _ in range(2):
p = Productor()
p.start()
for _ in range(5):
c = Cousmter()
c.start()
运行一下这个程序,结果还是一样,没区别,
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为2
消费者[1]:我消费了1个产品,现在产品的数量为: 1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
消费者[3]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[1]:我消费了1个产品,现在产品的数量为: 0
消费者[3]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
消费者[1]: 没有商品了,我不能消费了
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[5]:我消费了1个产品,现在产品的数量为: 0
消费者[4]: 没有商品了,我不能消费了
消费者[3]: 没有商品了,我不能消费了
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[1]:我消费了1个产品,现在产品的数量为: 0
生产者和消费者模型(一个写一个读),不能加互斥锁,容易造成死锁
1.3 条件锁
建一个条件锁
比如,消费者排队过长,不想消费就离开
import threading
from time import sleep
products = 0
# 创建一个互斥锁
# 生产者和消费者模型(一个写一个读),不能加互斥锁,容易造成死锁
# lock = threading.Lock()
# 创建一个条件锁
condition = threading.Condition()
# 定义一个生产者类
class Productor(threading.Thread):
ix = [0] #生产者的编号
# 重写一个函数
def __init__(self):
# 使用父类初始化
super().__init__()
self.ix[0] += 1
self.setName('生产者'+str(self.ix[0]))
def run(self):
global products
while True:
# if lock.acquire():
if condition.acquire():
if products<10:
#当产品数量少于10的时候就开始生产
products += 1
print('%s:库存不足10,我努力生产了一个产品,现在产品重量为%d'%(self.getName(),products))
else:
print('%s:库存充足,不需要继续生产,当前库存为:%d'%(self.getName(),products))
condition.wait()
# 如果当前线程不去执行生产操作就在资源上等待
condition.release()
# lock.release()
sleep(2)
# 定义一个消费者类
class Cousmter(threading.Thread):
ix = [0]
def __init__(self,ix=0):
super().__init__()
self.ix[0] += 1
self.setName('消费者'+str(self.ix))
def run(self):
global products
while True:
# if lock.acquire():
if condition.acquire():
if products >0:
products -= 1
print('%s:我消费了1个产品,现在产品的数量为: %d'%(self.getName(),products))
else:
print('%s: 没有商品了,我不能消费了'%self.getName())
condition.wait()
condition.release()
# lock.release()
sleep(2)
if __name__ == '__main__':
for _ in range(2):
p = Productor()
p.start()
for _ in range(5):
c = Cousmter()
c.start()
运行一下
E:\python1901\pythonSprider\venv\Scripts\python.exe E:/python1901/pythonSprider/day05/code2/5_生产者与消费者.py
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为2
消费者[1]:我消费了1个产品,现在产品的数量为: 1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
消费者[3]: 没有商品了,我不能消费了
消费者[4]: 没有商品了,我不能消费了
消费者[5]: 没有商品了,我不能消费了
消费者[1]: 没有商品了,我不能消费了
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为1
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为2
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为3
消费者[2]:我消费了1个产品,现在产品的数量为: 2
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为3
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为4
消费者[2]:我消费了1个产品,现在产品的数量为: 3
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为4
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为5
消费者[2]:我消费了1个产品,现在产品的数量为: 4
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为5
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为6
消费者[2]:我消费了1个产品,现在产品的数量为: 5
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为6
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为7
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为8
消费者[2]:我消费了1个产品,现在产品的数量为: 7
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为8
消费者[2]:我消费了1个产品,现在产品的数量为: 7
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为8
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为9
消费者[2]:我消费了1个产品,现在产品的数量为: 8
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为9
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为10
消费者[2]:我消费了1个产品,现在产品的数量为: 9
生产者2:库存不足10,我努力生产了一个产品,现在产品重量为10
消费者[2]:我消费了1个产品,现在产品的数量为: 9
生产者1:库存不足10,我努力生产了一个产品,现在产品重量为10
生产者2:库存充足,不需要继续生产,当前库存为:10
生产者1:库存充足,不需要继续生产,当前库存为:10
消费者[2]:我消费了1个产品,现在产品的数量为: 9
消费者[2]:我消费了1个产品,现在产品的数量为: 8
消费者[2]:我消费了1个产品,现在产品的数量为: 7
消费者[2]:我消费了1个产品,现在产品的数量为: 6
消费者[2]:我消费了1个产品,现在产品的数量为: 5
消费者[2]:我消费了1个产品,现在产品的数量为: 4
消费者[2]:我消费了1个产品,现在产品的数量为: 3
消费者[2]:我消费了1个产品,现在产品的数量为: 2
消费者[2]:我消费了1个产品,现在产品的数量为: 1
消费者[2]:我消费了1个产品,现在产品的数量为: 0
消费者[2]: 没有商品了,我不能消费了
资源号耗完了,也就结束了
2、队列
队列:是一种线性结构
from queue import Queue
# 创建一个队列
q = Queue(6) # 参数代表对列的最大长度,如果不传默认对列可以无限长
print(q.empty())
print(q.full())
print(q.qsize())
# 向对列中添加元素:入队
q.put("马云")
q.put("马化腾")
q.put("马龙")
q.put("马赛克")
q.put("老王")
q.put("大头儿子")
print(q.empty())
print(q.full())
print(q.qsize())
# q.put("小头爸爸") # 队列如果已满,就无法在添加
# 从队列中取元素:出队
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.empty())
print(q.full())
print(q.qsize())
# q.get() # 队列如果已经取空,则不允许再取,程序就会等待