程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(1)

Python当中的生产者和消费者的模型

发布于2019-08-08 10:07     阅读(470)     评论(0)     点赞(3)     收藏(5)


学习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() 
View Code

 接下来的代码就是为了解决阻塞的问题,我们希望当生产者生产完毕了就告诉消费者结束了卖完了,join的方法可以保证生产者先生产然后再对比;

      Event是事件,可以实现多进程间的通信!默认False,可以使用set方法改为true,也可以使用clear改回false,is_set可以判断目标是否是true

q.join()表示等待队列中的所有数据全部执行处理完毕

q.tast_done()表示该元素已经完成了处理,这样上面的join就可以感知到

守护进程是为了保证主进程结束时子进程也要一并结书

  !在代码的末尾我们设置了两个join,目的是感知进程结束,由于我们生产者末尾的join,所以代码不会一下结束,而是会等待消费者去消费队列的数据,由于消费者一直购买,所以当消费者购买不到产品的时候也就表示流水线结束了,这是整个代码底部的join就会感应到代码的结束也就可以结束所有进程了。

from multiprocessing import Process,JoinableQueue
from time import sleep
from random import randint

# 首先需要先构建一个生产者
def producer(food, name, q):
for i in range(1, 5):
sleep(randint(1, 2))
f = "\033[34m%s生产了%s ,代号:%s\033[0m" % (name, food, i)
print(f)
q.put(food)
q.join()#把队列q给设置为同步模式等待期内部的所有数据都被处理过代码才会结束

#构建一个消费者
def consumer(q, name):
while 1:
food = q.get()
sleep(randint(1, 2))
print("\033[31m%s消费了%s\033[0m" % (name, food))
q.task_done()#每当从队列当中获取一个值得时候就会自动计数


if __name__ == '__main__':
q = JoinableQueue()
p1 = Process(target=producer, args=("汉堡", "王师傅", q))
p2 = Process(target=producer, args=("三明治", "金师傅", q))
c1 = Process(target=consumer, args=(q, "陈先生"))
c2 = Process(target=consumer, args=(q, "王先生"))
c1.daemon = True #设置成守护进程这样就可以保证代码回一路运行到底
c2.daemon = True
p1.start()
p2.start()
c1.start()
c2.start()
p1.join()
p2.join()#感知主进程的结束这样就会自动结束子进程了

 

  

 



所属网站分类: 技术文章 > 博客

作者:085iitirtu

链接:https://www.pythonheidong.com/blog/article/12954/3c57718110a8c177a615/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

3 0
收藏该文
已收藏

评论内容:(最多支持255个字符)