Python当中的生产者和消费者的模型
学习python使得我快乐无比!!!
首先先解释一下什么是生产者和消费者模型
在我们的日常生活中,无处不是生产者和消费者,加入有一个买包子的人家,而你是一个想要买包子的人。那么买包子的商家就是生产者,而你就是一个消费者。
在编程中映入这一个概念是非常有必要的,我们都知道现在的计算机是多核心的,很多手机都是八核心起步了,多核心也就意味着多进程同时运行,你的计算机可以同时处理多个指令这样处理的速度的以加快,所以我们映入该概念。
概念:首先举一个例子就是我们的爬虫程序,我们都知道爬虫就是一次性的吧网络上的数据快速的爬取下来并且放入本地计算机或者云端服务器供我们未来使用,那么我们的爬虫程序其实就是这样的一个生产者,但是我们知道计算机的性能和效率都很高,假如一个爬虫程序不停工作可以生产出大量的数据,但是我们的处理程序运行起来却比较的满不可能一次性处理这么多的程序这就会爆内存,实在是放不下了只好先放在内存里面,但是越来越多的数据会导致内存被占满结果就爆了。
生产者--->流水线---->消费者
这样就出现了一个中继的东西我们占时管它叫做流水线,我们有很多的生产者同时生产数据到流水线上,然后消费者在从流水线上取下,这样我们可以有多个生产者同时生产提升了效率,同时也可以容纳多个消费者在流水线上消费,这样的话就可以解决上面的问题了,同时:!!我们也可以引入多进程的工作进入了,生产者太少了的时候就多开几个进程生产,如果消费者的处理能力太弱了就多开几个进程同时处理这样就可以快很多了!
列子1
注意:代码的思想(这是初步的思想)
导入了随机数时间来休眠是为了模拟网络延时的不可控因素,可以看到我们创建了10个生产者生产了一轮产品,但是消费者过多了说以代码会处于阻塞状态接下来会解决这个问题!
1 from multiprocessing import process, queue 2 from time import sleep 3 from random import randint 4 5 # 首先需要先构建一个生产者 6 def producer(food, name, q): 7 for i in range(1, 11): 8 sleep(randint(1, 2)) 9 f = "\033[34m%s生产了%s ,代号:%s\033[0m" % (name, food, i) 10 print(f) 11 q.put(food) 12 13 #构建一个消费者 14 def consumer(q, name): 15 while 1: 16 food = q.get() 17 sleep(randint(1, 2)) 18 print("\033[31m%s消费了%s\033[0m" % (name, food)) 19 20 if __name__ == '__main__': 21 q = queue() 22 p1 = process(target=producer, args=("汉堡", "王师傅", q)) 23 p2 = process(target=producer, args=("三明治", "金师傅", q)) 24 c1 = process(target=consumer, args=(q, "陈先生")) 25 c2 = process(target=consumer, args=(q, "王先生")) 26 p1.start() 27 p2.start() 28 c1.start() 29 c2.start()
接下来的代码就是为了解决阻塞的问题,我们希望当生产者生产完毕了就告诉消费者结束了卖完了,join的方法可以保证生产者先生产然后再对比;
event是事件,可以实现多进程间的通信!默认false,可以使用set方法改为true,也可以使用clear改回false,is_set可以判断目标是否是true
from multiprocessing import process, queue, event
from time import sleep
from random import randint
# 首先需要先构建一个生产者
def producer(food, name, q):
for i in range(1, 11):
sleep(randint(1, 2))
f = "\033[34m%s生产了%s ,代号:%s\033[0m" % (name, food, i)
print(f)
q.put(food)
#构建一个消费者
def consumer(q, name, e):
while 1:
if e.is_set():
food = q.get()
sleep(randint(1, 2))
print("\033[31m%s消费了%s\033[0m" % (name, food))
else:
break
if __name__ == '__main__':
q = queue()
e = event()
e.set()
p1 = process(target=producer, args=("汉堡", "王师傅", q))
p2 = process(target=producer, args=("三明治", "金师傅", q))
c1 = process(target=consumer, args=(q, "陈先生", e))
c2 = process(target=consumer, args=(q, "王先生", e))
p1.start()
p2.start()
c1.start()
c2.start()
p1.join()
p2.join()
e.clear()