微信搜索superit|邀请体验:大数据, 数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

python守护进程+JoinableQueue队列实现生产者消费者模型

python aide_941 2℃ 0评论

from multiprocessing import Process,JoinableQueue
import time,random,os

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

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

#参数介绍:
maxsize是队列中允许最大项数,省略则无大小限制。    
#方法介绍:
JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止,也就是队列中的数据全部被get拿走了。

看lock_tickets_JoinableQueue.py文件场景!!

'''

def consumer(q):
    while True:
        res=q.get()
        # time.sleep(random.randint(1,3))
        time.sleep(random.random())
        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))
        time.sleep(random.random())
        res='%s%s' %(name,i)
        q.put(res)
        print('\033[44m%s 生产了 %s\033[0m' %(os.getpid(),res))
    print('%s生产结束'%name)
    q.join() #生产完毕,使用此方法进行阻塞,直到队列中所有项目均被处理。
    print('%s生产结束~~~~~~'%name)

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
    # 如果不加守护,那么主进程结束不了,但是加了守护之后,必须确保生产者的内容生产完并且被处理完了!!!
    # 所有必须还要在主进程给生产者设置join,才能确保生产者生产的任务被执行完了,
    # 并且能够确保守护进程在所有任务执行完成之后才随着主进程的结束而结束。

    #开始,,注意顺序!!# 等待逻辑顺序:主进程等--->p1,p2,p3等---->c1,c2
    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也没有存在的价值了,不需要继续阻塞在进程中影响主进程了。应该随着主进程的结束而结束,所以设置成守护进程就可以了。

 

转载请注明:SuperIT » python守护进程+JoinableQueue队列实现生产者消费者模型

喜欢 (0)or分享 (0)

您必须 登录 才能发表评论!