生产者消费者模型(★)

平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
程序中有两类角色:生产数据、消费数据
实现方式:生产->队列->消费。

通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
通过队列的方式实现了程序解耦(生产者不需要管消费者的消费能力,不断的生产)
#消息队列作为中间件,接受生产者发来的消息,并且供消费者拿走进行消费。
实现了异步\

示例:

from multiprocessing import Process,Queue
import time,random,os
def consumer(q):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('\033[45m%s 吃 %s\033[0m' %(os.getpid(),res)) def producer(q):
for i in range(10):
time.sleep(random.randint(1,3))
res='卤肉%s' %i
q.put(res)
print('\033[44m%s 生产了 %s\033[0m' %(os.getpid(),res)) if __name__ == '__main__':
q=Queue()
#生产者们:即制造东西
p1=Process(target=producer,args=(q,)) #消费者们:即使用的
c1=Process(target=consumer,args=(q,)) #开始
p1.start()
c1.start()
print('主')
#这个示例会因最后生产者生产完了,但消费者取完后还在取一直阻塞在get()这里。

生产者可以在自己生产完后停止往队列中传递,但是消费者需要不断的消费,在消费完生产的数据后无法停止,会一直处于等待状态。

#若是在生产结束后发送none,会因存在多个生产、消费者时发多个none信号。

为了避免这种状态,需要使用JoinableQueue方法来实现结束的信号。

JoinableQueue 队列允许项目的使用者通知生成者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。

消费者在每次消费完后执行q.task_done() 往消息队列中发送信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常。
q.join() 调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止。可以判断生产者生产的个数与消费者消费的个数,并且关闭,q.join()需要加到生产者生产完(结束)后,判断完成后会继续执行主进程代码,在执行完后还会被消费者的消费卡主,故把消费者设置成守护进程。 示例:

from multiprocessing import Process,JoinableQueue
import time,random,os
def consumer(q):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('\033[45m%s 吃 %s\033[0m' %(os.getpid(),res)) q.task_done() #向q.join()发送一次信号,证明一个数据已经被取走了 def producer(name,q):
for i in range(10):
time.sleep(random.randint(1,3))
res='%s%s' %(name,i)
q.put(res)
print('\033[44m%s 生产了 %s\033[0m' %(os.getpid(),res))
q.join() if __name__ == '__main__':
q=JoinableQueue()
#生产者们:即制造东西
p1=Process(target=producer,args=('肉',q))
p2=Process(target=producer,args=('骨头',q))
p3=Process(target=producer,args=('馒头',q)) #消费者们:即使用的
c1=Process(target=consumer,args=(q,))
c2=Process(target=consumer,args=(q,))
c1.daemon=True
c2.daemon=True #开始
p_l=[p1,p2,p3,c1,c2]
for p in p_l:
p.start() p1.join()
p2.join()
p3.join()
print('主') #主进程等--->p1,p2,p3等---->c1,c2
#p1,p2,p3结束了,证明c1,c2肯定全都收完了p1,p2,p3发到队列的数据
#因而c1,c2也没有存在的价值了,应该随着主进程的结束而结束,所以设置成守护进程

Python--10、生产者消费者模型的更多相关文章

  1. python之生产者消费者模型

    #Auther Bob #--*--conding:utf-8 --*-- #生产者消费者模型,这里的例子是这样的,有一个厨师在做包子,有一个顾客在吃包子,有一个服务员在储存包子,这个服务员我们就可以 ...

  2. Python多线程-生产者消费者模型

    用多线程和队列来实现生产者消费者模型 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import threading imp ...

  3. (python)生产者消费者模型

    生产者消费者模型当中有两大类重要的角色,一个是生产者(负责造数据的任务),另一个是消费者(接收造出来的数据进行进一步的操作). 为什么要使用生产者消费者模型? 在并发编程中,如果生产者处理速度很快,而 ...

  4. python 之生产者消费者模型

    进程实现: import time,random from multiprocessing import Process,Queue def producer(name,q): count= 0 wh ...

  5. python实现生产者消费者模型

    生产者消费之模型就是,比如一个包子铺,中的顾客吃包子,和厨师做包子,不可能是将包子一块做出来,在给顾客吃,但是单线程只能这麽做,所以用多线程来执行,厨师一边做包子,顾客一边吃包子,当顾客少时,厨师做的 ...

  6. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  7. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  8. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  9. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))

    昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...

  10. python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型

    1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...

随机推荐

  1. Git学习总结(14)——Git使用前的注意事项

    连接方式https.ssh 在使用git的时候,不管你的服务器是开源平台github还是私服gitlab,你都需要clone仓库到本地,这个clone的时候就需要你选择连接方式.这个连接方式决定了你与 ...

  2. empty array & Array.from

    empty array bug const duplicationArray = (arr = [], times = 2, debug = false) => { let result = [ ...

  3. 史上超全面的Neo4j使用指南

    Create by yster@foxmail.com 2018-7-10 我的博客:https://blog.csdn.net/yueshutong123 W3Cschool文档:https://w ...

  4. 【Java基础】Java基本数据类型与位运算

    1.赋值运算符 赋值使用操作符“=”.它的意思是“取右边的值(即右值),把它复制给左边(即左值)”.右值可以是任何 常数.变量或者表达式 (只要它能 生成 一个值就行).但左值必须是一个明确的,已命名 ...

  5. MYSQL中有关数据库的简单操作

    #创建数据库CREATE DATABASE day01; #查询所有数据库SHOW DATABASES; #查看某个数据库定义信息SHOW CREATE DATABASE day01; #查询正在使用 ...

  6. Linux基本命令总结(初学者可以借鉴学习)

    Linux基本常用命令 个人在平时项目中用到的一些常规命令总结下 删除文件夹命令:rm -rf 目录名字 添加模式:按i 退出编辑模式:ese左上角键 首先先按esc退出进入一个模式然后再输入wq或者 ...

  7. 深入学习理解java-ThreadLocal

    导读 首先,ThreadLocal 不是用来解决共享对象的多线程訪问问题的,普通情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其它线程是不须要訪问的,也訪问不到 ...

  8. leetcode_Product of Array Except Self

    描写叙述: Given an array of n integers where n > 1, nums, return an array output such that output[i]  ...

  9. python练习-跳出多层循环和购物车

    跳出多层循环:三层循环,最里层直接跳出3层 在Python中,函数运行到return这一句就会停止,因此可以利用这一特性,将功能写成函数,终止多重循环 def work(): for i in ran ...

  10. 浅析C++多重继承

    继承是面向对象的三大特征之中的一个. 可是对于继承的实现和使用方式,各种不同的面向对象语言有各自的观点.有些语言支持多重继承.而有些语言则仅仅支持单一继承. 多重继承的确引入了较大的复杂度.那么.在不 ...