JoinableQueue队列实现消费之生产者模型

方法介绍

JoinableQueue([maxsize])

创建可连接的共享进程队列。这就像是一个Queue对象,但队列允许项目的使用者通知生产者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。

JoinableQueue的实例p除了与Queue对象相同的方法之外,还具有以下方法:

  • q.task_done()
    • 使用者使用此方法发出信号,表示q.get()返回的项目已经被处理。如果调用此方法的次数大于从队列中删除的项目数量,将引发ValueError异常。用于消费者,是指每消费队列中的一个数据,就给join返回一个标识        
  • q.join()
    • ​​​​​​​生产者将使用此方法进行阻塞,直到队列中所有项目均被处理。阻塞将持续到为队列中的每个项目均调用q.task_done()方法为止。
  • 下面的例子说明如何建立永远运行的进程,使用和处理队列上的项目。生产者将项目放入队列,并等待它们被处理。用于生产者,等待 task_done的返回结果,生产者就获得消费者当前消费了多少个数据
import os,time
from multiprocessing import Process,JoinableQueue

def producer(name,q):
    for i in range(10):
        res = '%s%s'%(name,i)
        q.put(res)
        print('\033[45m %s生产了 %s\033[0m'%(os.getpid(),res))
    q.join()
def  consumer(q):
    while True:
        res = q.get()
        print('\033[46m%s 吃 %s\033[0m' % (os.getpid(), res))
        q.task_done()  # 向q.join()发送一次信号,证明一个数据已经被取走了

if __name__ == '__main__':
    q=JoinableQueue()
    #生产者们:即厨师们
    p1=Process(target=producer,args=('rose',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,))
    c2.daemon = True
    c1.daemon = True  #这个要放在启动进程前面代表p.daemon:.
    # 默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,
    # p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
    #开始 
    p_l=[p1,p2,p3,c1,c2]
    for p in p_l:
        p.start()

    # p1.join()
    # p2.join()
    # p3.join()
    # c1.start()
    # c2.start()
    time.sleep(2)  #加上时间让子进程执行完
    print('主')

结果:

 3054生产了 rose0
 3054生产了 rose1
 3054生产了 rose2
 3054生产了 rose3
 3054生产了 rose4
 3054生产了 rose5
 3054生产了 rose6
 3054生产了 rose7
 3054生产了 rose8
 3054生产了 rose9
主
 3057生产了 老王0
 3057生产了 老王1
 3057生产了 老王2
 3057生产了 老王3
 3057生产了 老王4
 3057生产了 老王5
 3057生产了 老王6
 3057生产了 老王7
 3057生产了 老王8
 3057生产了 老王9
3059 吃 rose0
 3055生产了 波姐0
 3055生产了 波姐1
 3055生产了 波姐2
 3055生产了 波姐3
 3055生产了 波姐4
 3055生产了 波姐5
 3055生产了 波姐6
 3055生产了 波姐7
 3055生产了 波姐8
 3055生产了 波姐9
3058 吃 rose1
3058 吃 rose2
3058 吃 rose3
3058 吃 rose4
3058 吃 rose5
3058 吃 rose6
3058 吃 rose7
3058 吃 rose8
3058 吃 rose9
3058 吃 老王0
3058 吃 老王1
3058 吃 老王2
3058 吃 老王3
3058 吃 老王4
3058 吃 老王5
3058 吃 老王6
3058 吃 老王7
3058 吃 老王8
3058 吃 老王9
3058 吃 波姐0
3058 吃 波姐1
3058 吃 波姐2
3058 吃 波姐3
3058 吃 波姐4
3058 吃 波姐5
3058 吃 波姐6
3058 吃 波姐7
3058 吃 波姐8
3058 吃 波姐9

主进程等--->p1,p2,p3等---->c1,c2 41
p1,p2,p3结束了,证明c1,c2肯定全都收完了p1,p2,p3发到队列的数据 
因而c1,c2也没有存在的价值了,不需要继续阻塞在进程中影响主进程了。应该随着主进程的结束而结束,所以设置成守护进程就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值