9.8 生产者消费者模型

该模型中包含两类重要的角色:

1、生产者:将负责造数据的任务比喻为生产者 2、消费者:接收生产者造出的数据来做进一步的处理的被比喻成消费者

实现生产者消费者模型三要素:1、生产者 2、消费者 3、队列

什么时候用该模型:

程序中出现明显的两类任何,一类任务是负责生产,另外一类任务是负责处理生产的数据的

该模型的好处:

1、实现了生产者与消费者解耦和

2、平衡了生产力与消费力,即生产者可以一直不停地生产,消费者可以不停地处理,因为二者不再直接沟通的,而是跟队列沟通,从而提高程序整体处理数据的速度

import time
import random
from multiprocessing import Process,Queue
def consumer(name,q):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('\033[46m消费者===》%s 吃了 %s\033[0m' %(name,res))

def producer(name,q,food):
for i in range(5):
time.sleep(random.randint(1,2))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m生产者者===》%s 生产了 %s\033[0m' %(name,res))

if __name__ == '__main__':
q=Queue() #1、共享的盆 p1=Process(target=producer,args=('egon',q,'包子')) #2、生产者们
p2=Process(target=producer,args=('刘清政',q,'泔水'))
p3=Process(target=producer,args=('杨军',q,'米饭'))

c1=Process(target=consumer,args=('alex',q)) #3、消费者们
c2=Process(target=consumer,args=('xxx',q))

p1.start()
p2.start()
p3.start()
c1.start()
c2.start()

9.81 守护进程的应用

问题:消费者c1和c2在取空了q之后,则一直处于死循环中且卡在q.get()这一步

解决方式无非是让生产者在生产完毕后,往队列中再发一个结束信号,这样消费者在接收到结束信号后就可以break退出死循环

import time
import random
from multiprocessing import Process,Queue

def consumer(name,q):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print('\033[46m消费者===》%s 吃了 %s\033[0m' %(name,res))

def producer(name,q,food):
for i in range(5):
time.sleep(random.randint(1,2))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m生产者者===》%s 生产了 %s\033[0m' %(name,res))
#q.put(None)
if __name__ == '__main__':
#1、共享的盆
q=Queue()
#2、生产者们
p1=Process(target=producer,args=('egon',q,'包子'))
p2=Process(target=producer,args=('刘清政',q,'泔水'))
p3=Process(target=producer,args=('杨军',q,'米饭'))
#3、消费者们
c1=Process(target=consumer,args=('alex',q))
c2=Process(target=consumer,args=('梁书东',q))

p1.start()
p2.start()
p3.start()
c1.start()
c2.start()

p1.join()# 在生产者生产完毕后,往队列的末尾添加一个结束信号None
p2.join()
p3.join()
# 有几个消费者就应该放几个结束信号
q.put(None)#队列是共享的,主进程同样可以往队列里放None
q.put(None)

升级版:设置守护进程,向队列发送结束信号,解决管道取空阻塞问题

JoinableQueue([maxsize]):这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。

  • maxsize是队列中允许最大项数,省略则无大小限制

  • q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常

  • q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止

import time
import random
from multiprocessing import Process,JoinableQueue

def consumer(name,q):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print('\033[46m消费者===》%s 吃了 %s\033[0m' %(name,res))
q.task_done() #向q.join()发送一次信号,证明一个数据已经被取走了

def producer(name,q,food):
..........
if __name__ == '__main__':
#1、共享的盆
q=JoinableQueue()
#2、生产者们
p1=Process(target=producer,args=('egon',q,'包子'))
p2=Process(target=producer,args=('刘清政',q,'泔水'))
p3=Process(target=producer,args=('杨军',q,'米饭'))
#3、消费者们
c1=Process(target=consumer,args=('alex',q))
c2=Process(target=consumer,args=('梁书东',q))
c1.daemon=True
c2.daemon=True

p1.start()
p2.start()
p3.start()
c1.start()
c2.start()

p1.join()# 确定生产者确确实实已经生产完毕
p2.join()
p3.join()
# 在生产者生产完毕后,拿到队列中元素的总个数,然后直到元素总数变为0,q.join()这一行代码才算运行完毕
q.join()
#q.join()一旦结束就意味着队列确实被取空,消费者已经确确实实把数据都取干净了
print('主进程结束')

python 之 并发编程(生产者消费者模型、守护进程的应用)的更多相关文章

  1. (并发编程)进程IPC,生产者消费者模型,守护进程补充

    一.IPC(进程间通信)机制进程之间通信必须找到一种介质,该介质必须满足1.是所有进程共享的2.必须是内存空间附加:帮我们自动处理好锁的问题 a.from multiprocessing import ...

  2. python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)

    #######################总结######### 主要理解 锁      生产者消费者模型 解耦用的   队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...

  3. 网络编程 生产者消费者模型 GiL

    守护进程: 注意事项: 1.必须在p.start()前 2.守护进程不能开子进程 3.如果主进程的运行时间快于子进程,那么就只有主进程的结果,没有守护进程的结果,因为守护进程没有进行完.反之会得到两个 ...

  4. Java多线程-并发协作(生产者消费者模型)

    对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...

  5. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  6. Java 并发编程 生产者消费者模式

    本文部分摘自<Java 并发编程的艺术> 模式概述 在线程的世界里,生产者就是生产数据的线程,消费者就是消费数据的数据.生产者和消费者彼此之间不直接通信,而是通过阻塞队列进行通信,所以生产 ...

  7. c++并发练习---生产者消费者模型

    问题:有一个生产者,多个消费者,生产者每生产一个,放入队列,多个消费者顺序从队列中取出数据,打印最终结果. 分析:首先这题,我本意应该设计成如下模型:生产者单开一个线程,向队列中放入数据,而消费者在锁 ...

  8. java并发编程(四)守护进程 线程阻塞的四种情况

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17099981 守护线程   Java中有两类线程:User Thread(用户线程).Da ...

  9. 守护进程,进程安全,IPC进程间通讯,生产者消费者模型

    1.守护进程(了解)2.进程安全(*****) 互斥锁 抢票案例3.IPC进程间通讯 manager queue(*****)4.生产者消费者模型 守护进程 指的也是一个进程,可以守护着另一个进程 一 ...

  10. 【Windows】用信号量实现生产者-消费者模型

    线程并发的生产者-消费者模型: 1.两个进程对同一个内存资源进行操作,一个是生产者,一个是消费者. 2.生产者往共享内存资源填充数据,如果区域满,则等待消费者消费数据. 3.消费者从共享内存资源取数据 ...

随机推荐

  1. 批量更新表注释 mysql

    -- 生成更新语句 SELECT CONCAT( 'ALTER TABLE ', T2.table_name, ' COMMENT ''', T1.TABLE_COMMENT, ''';' ) sql ...

  2. mac安装rust的pyo3模块

    Rust 发布的工具链包括了 stable.beta 和 nightly 三种不同版本. nightly 是最激进的版本,包含了大量(可能不稳定)的新/高级特性.stable 版本目前可能还不支持一些 ...

  3. 从零开始带你成为JVM实战高手

    专栏大纲 1.核心gc 内存回收以及提前设置内存大小.

  4. 远程桌面工具mRemoteNG与Tsmmc

    一.Tsmmc.msc远程管理工具.1.下载链接:https://pan.baidu.com/s/1tV_xP-ITWyKKzAxLSlGxlw 密码:0jrt 将目录下的mstsmhst.dll.m ...

  5. Swagger 慢

    Swagger 慢 - 国内版 Binghttps://cn.bing.com/search?FORM=U227DF&PC=U227&q=Swagger+%E6%85%A2 rest框 ...

  6. Docker 记一次 docker-compose 完整实践(转)

    本文介绍docker-compose实践时的一些疑问与解决方案, 可能对新手略有帮助, 因此整理成文. 有不妥之处欢迎指摘! Q1: docker-compose 如何安装? A1: https:// ...

  7. Typora 精美而强大的Markdown编辑器

    Typora 精美而强大的Markdown编辑器  转 https://www.jianshu.com/p/45e284645d30 Markdown编辑器千千万,可是有颜值.功能强并且免费的,就没有 ...

  8. kinova roslaunch j2s7s300_moveit_config j2s7s300_demo.launc logs1

    luo@luo-ThinkPad-W530:~$ luo@luo-ThinkPad-W530:~$ luo@luo-ThinkPad-W530:~$ luo@luo-ThinkPad-W530:~$ ...

  9. matlab基本函数min

    一起来学演化计算-matlab基本函数min 觉得有用的话,欢迎一起讨论相互学习~Follow Me 找到数组中最小的元素 语法 M = min(A) 返回A的最小元素 如果A是一个向量,那么min( ...

  10. Windows自动计划任务与ParamStr详解

    ParamStr函数: ParamStr(1),..ParamStr(N) ParamStr(1)代表程序入口的第一个参数,同理,ParamStr(N)代表第N个参数.可通过如下操作进行参数的赋值. ...