zoukankan      html  css  js  c++  java
  • python_ joinablequeue详解

    2019-5-20未命名文件

    欢迎使用 小书匠(xiaoshujiang)编辑器,您可以通过 小书匠主按钮>模板 里的模板管理来改变新建文章的内容。

    joinablequeue实现生产者消费者模型

    1、使用Queue实现的代码

    import time
    import random
    from multiprocessing import Process,Queue
    
    def producer(q,name,food):
        for i in range(2):
            time.sleep(random.random())
            fd = '%s%s'%(food,i)
            q.put(fd)
            print('%s生产了一个%s'%(name,food))
    
    def consumer(q,name):
        while True:
            food = q.get()
            if not food:break
            time.sleep(random.randint(1,3))
            print('%s吃了%s'%(name,food))
    
    
    def cp(c_count,p_count):
        q = Queue(10)
        for i in range(c_count):
            Process(target=consumer, args=(q, '灰太狼')).start()
        p_l = []
        for i in range(p_count):
            p1 = Process(target=producer, args=(q, '喜洋洋', '包子'))
            p1.start()
            p_l.append(p1)
        for p in p_l:p.join()
        for i in range(c_count):
            q.put(None)
    if __name__ == '__main__':
        cp(2,3)
    ----------------结果:
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    灰太狼吃了包子1
    灰太狼吃了包子0
    灰太狼吃了包子0
    灰太狼吃了包子0
    灰太狼吃了包子1
    灰太狼吃了包子1

    2、使用joinablequeue实现队列
    (1)消费者不需要判断从队列里拿到None再退出执行消费者函数了
    (2)消费者每次从队列里面q.get()一个数据,处理过后就使用队列.task_done()
    (3)生产者for循环生产完所有产品,需要q.join()阻塞一下,对这个队列进行阻塞。
    (4)启动一个生产者,启动一个消费者,并且这个消费者做成守护进程,然后生产者需要p.join()阻塞一下。
    (5)我启动了生产者之后,生产者函数一直在生成数据,直到生产完所有数据将队列q.join()一下,意思是当我生产的数据都被消费者消费完之后 队列的阻塞才结束。
    (6)结束过程:消费者这边是每消费完一个数据给队列返回一个q.task_done(),直到所有的数据都被消费完之后,生产者函数这边的队列.阻塞结束了,队列阻塞结束了生产者函数执行结束了。生产者函数结束了,那么p.join()生产者进程对象就结束了。生产者进程对象结束了整个主进程的代码就执行结束了。主进程代码结束了守护进程及消费者进程也结束了

    import time
    import random
    from  multiprocessing import JoinableQueue,Process
    def producer(q,name,food):
        for i in range(5):
            time.sleep(random.random())
            fd = '%s%s'%(food,i+1)
            q.put(fd)
            print('%s生产了一个%s'%(name,food))
        q.join()#(3)生产者for循环生产完所有产品,需要q.join()阻塞一下,对这个队列进行阻塞。
    #(5)我启动了生产者之后,生产者函数一直在生成数据,直到生产完所有数据将队列q.join()一下,意思是当我生产的数据都被消费者消费完之后 队列的阻塞才结束。
    def consumer(q,name): #(1)消费者不需要像Queue那样判断从队列里拿到None再退出执行消费者函数了
        while True:
            food = q.get()
            time.sleep(random.random())
            print('%s吃了%s'%(name,food))
            q.task_done() #(2)消费者每次从队列里面q.get()一个数据,处理过后就使用队列.task_done()
    if __name__ == '__main__':
        jq = JoinableQueue()
        p =Process(target=producer,args=(jq,'喜洋洋','包子')) #
        p.start() #(4)启动一个生产者,启动一个消费者,并且这个消费者做成守护进程,然后生产者需要p.join()阻塞一下。
        c = Process(target=consumer,args=(jq,'灰太狼'))
        c.daemon = True #
        c.start()
        p.join() 
    #(6)结束过程:消费者这边是每消费完一个数据给队列返回一个q.task_done(),直到所有的数据都被消费完之后,生产者函数这边的队列.阻塞结束了,队列阻塞结束了生产者函数执行结束了。生产者函数结束了,那么p.join()生产者进程对象就结束了。生产者进程对象结束了整个主进程的代码就执行结束了。主进程代码结束了守护进程即消费者进程也结束了
    ---------------结果:
    喜洋洋生产了一个包子
    灰太狼吃了包子1
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    喜洋洋生产了一个包子
    灰太狼吃了包子2
    灰太狼吃了包子3
    灰太狼吃了包子4
    灰太狼吃了包子5
    
    import time
    import random
    from  multiprocessing import JoinableQueue,Process
    def producer(q,name,food):
        for i in range(5):
            time.sleep(random.random())
            fd = '%s%s'%(food,i+1)
            q.put(fd)
            print('%s生产了一个%s'%(name,food))
        q.join()
    def consumer(q,name):
        while True:
            food = q.get()
            time.sleep(random.random())
            print('%s吃了%s'%(name,food))
            q.task_done()
    if __name__ == '__main__':
        jq = JoinableQueue()
        p =Process(target=producer,args=(jq,'喜洋洋','包子'))
        p.start()
        c = Process(target=consumer,args=(jq,'灰太狼'))
        c.daemon = True
        c.start()
        p.join()

    3、二者区别
    1)Queue有多少消费者,就要put多少个None。要在消费者函数添加if 不是真(非None数据)就退出死循环
    2)二者效果一样但是从程序员角度看,joinablequeue更加严谨,更符合编程思维

  • 相关阅读:
    linux 命令——19 find (转)
    linux 命令——18 locate (转)
    linux 命令——17 whereis(转)
    linux 命令——16 which(转)
    linux 命令——15 tail (转)
    linux 命令——14 head (转)
    Java for LeetCode 038 Count and Say
    Java for LeetCode 037 Sudoku Solver
    Java for LeetCode 036 Valid Sudoku
    Java for LeetCode 035 Search Insert Position
  • 原文地址:https://www.cnblogs.com/machangwei-8/p/10895554.html
Copyright © 2011-2022 走看看