zoukankan      html  css  js  c++  java
  • Python——Queue模块以及生产消费者模型

    1.了解Queue

    Queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递

    |queue.Queue|先进先出队列|
    |queue.LifoQueue|后进先出队列|
    |queue.PriorityQueue|优先级队列|
    |queue.deque|双线队列|

    了解python队列 https://www.cnblogs.com/itogo/p/5635629.html

    ----------------------------------------------------------------------------------------

    2.生产者和消费者模型

     生产者和消费者模型

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

    为什么要使用生产者和消费者模式

    在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

    什么是生产者消费者模式

    生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

    例子1

    # ecoding=utf-8
    import Queue
    import threading,time
     
    q = Queue.Queue(maxsize=10)
    def Producer(name):
        count =1
        while True:
            q.put("包子 %s" % count)
            print "做了包子",count
            count +=1
            time.sleep(0.5)
    def Consumer(name):
        while True :
            print "[%s] 取到[%s] 并且吃了它..." %(name,q.get())
            time.sleep(1)
     
    p = threading.Thread(target=Producer,args=("Lily",))
    c = threading.Thread(target=Consumer,args=("Lilei",))
    c1 = threading.Thread(target=Consumer,args=("Ahi",))
     
    p.start()
    c.start()
    c1.start()

    运行结果

    做了包子 1
    [Lilei] 取到[包子 1] 并且吃了它...
    做了包子 2
    [Ahi] 取到[包子 2] 并且吃了它...
    做了包子 3
    [Lilei] 取到[包子 3] 并且吃了它...
    做了包子 4
    [Ahi] 取到[包子 4] 并且吃了它...
    做了包子 5[Lilei] 取到[包子 5] 并且吃了它...
    
    做了包子 [Ahi] 取到[包子 6] 并且吃了它...
    6
    做了包子 7[Lilei] 取到[包子 7] 并且吃了它...
    
    做了包子 8
     [Ahi] 取到[包子 8] 并且吃了它...
    做了包子 9
    [Lilei] 取到[包子 9] 并且吃了它...
    做了包子 10
     [Ahi] 取到[包子 10] 并且吃了它...
    做了包子 11
    [Lilei] 取到[包子 11] 并且吃了它...

    例子2

    # ecoding=utf-8
    from threading import current_thread, Thread
    import time
    import random
    import queue
    
    q = queue.Queue(5)
    
    class Productor(Thread):
        def run(self):
            name = current_thread().getName()
            nums = range(100)
            while 1:
                nowput = random.choice(nums)
                if q.full():  # 消息队列满则停止生产
                    print "队列已经达到上限{0}".format(q.qsize())
                    time.sleep(10)
                q.put(nowput)
                print "生产者{0}生产了{1}".format(name, nowput)
                sl = random.choice([1, 2, 3])
                time.sleep(sl)  
                print "生产者休息了{0}秒".format(sl)
    
    class Consumer(Thread):
        def run(self):
            name = current_thread().getName()
            while 1:
                if q.empty():  # 消息队列空的时候则暂停消费
                    print "队列空了,暂停消费"
                    time.sleep(5)
                num = q.get()
                q.task_done()
                print "消费者{0}消费了{1}".format(name, num)
                sl = random.choice([1, 2, 3])
                time.sleep(sl)
                print "消费者休息了{0}秒".format(sl)
    
    
    if __name__ == '__main__':
        p1 = Productor()
        p1.start()
        p2 = Productor()
        p2.start()
        c1 = Consumer()
        c1.start()
        c2 = Consumer()
        c2.start()
        c3 = Consumer()
        c3.start()

    运行结果

    生产者Thread-1生产了90
    生产者Thread-2生产了61
    消费者Thread-3消费了90
     消费者Thread-4消费了61
    队列空了,暂停消费
    
    消费者休息了1秒
    队列空了,暂停消费
    生产者休息了2秒
    生产者Thread-1生产了30
     消费者休息了2秒
    消费者Thread-3消费了30
    生产者休息了2秒
    生产者Thread-2生产了15
    消费者休息了1秒
    消费者Thread-3消费了15
    生产者休息了2秒
    生产者Thread-1生产了11
     生产者休息了2秒
    生产者Thread-2生产了94
    生产者休息了1秒
    生产者Thread-1生产了18
    消费者Thread-5消费了11
    生产者休息了2秒消费者Thread-4消费了94
    消费者休息了3秒
    消费者Thread-3消费了18

    参考了

    https://blog.csdn.net/wyb199026/article/details/80788570

    http://www.cnblogs.com/qing-chen/p/7684812.html

  • 相关阅读:
    引用同一解决方案里的其他项目
    使用OpenXml打开word文档中嵌入的另一个文档
    把最近踩的坑总结一下(2)——二级MSoffice题库软件自动更新版本V2.0
    把最近踩的坑总结一下(1)——二级MSoffice题库软件自动更新版本V2.0
    脑残系列(1)
    前端Crypto.JS加密解密
    在构造函数时 new做的四件事情
    js创建对象的四种方式
    VS-Code背景图片
    单行、多行文本溢出以省略号显示
  • 原文地址:https://www.cnblogs.com/Micang/p/9777713.html
Copyright © 2011-2022 走看看