zoukankan      html  css  js  c++  java
  • 12 生产者消费者模式 解耦

    1. 生产者消费者模式的说明

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

      在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。

      同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

      2)什么是生产者消费者模式

      生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,

      而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

      这个阻塞队列就是用来给生产者和消费者解耦的。纵观大多数设计模式,都会找一个第三者出来进行解耦,

      3).中间是缓冲池,队列

        多进程程序中,产生数据和处理数据速度不匹配的问题:解耦

    2.队列(FIFO)和栈(LIFO)

      Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。

      这些队列都实现了锁原语(可以理解为原子操作,即要么不做,要么就做完),能够在多线程中直接使用。可以使用队列来实现线程间的同步。

        

     3.解耦

          

          

    4.用FIFO队列实现上述生产者与消费者问题,

      1) Queue的说明

    1. 对于Queue,在多线程通信之间扮演重要的角色
    2. 添加数据到队列中,使用put()方法
    3. 从队列中取数据,使用get()方法
    4. 判断队列中是否还有数据,使用qsize()方法
    • 这个阻塞队列就是用来给生产者和消费者解耦的
    #encoding=utf-8
    import threading
    import time
    
    #python2中
    from Queue import Queue
    
    #python3中
    # from queue import Queue
    
    class Producer(threading.Thread):
        def run(self):
            global queue
            count = 0
            while True:
                if queue.qsize() < 1000:
                    for i in range(100):
                        count = count +1
                        msg = '生成产品'+str(count)
                        queue.put(msg)
                        print(msg)
                time.sleep(0.5)
    
    class Consumer(threading.Thread):
        def run(self):
            global queue
            while True:
                if queue.qsize() > 100:
                    for i in range(3):
                        msg = self.name + '消费了 '+queue.get()
                        print(msg)
                time.sleep(1)
    
    
    if __name__ == '__main__':
        queue = Queue()
    
        for i in range(500):
            queue.put('初始产品'+str(i))
        for i in range(2):
            p = Producer()
            p.start()
        for i in range(5):
            c = Consumer()
            c.start()

           

    5.实现方式

    1.  进程
    2. 线程
    3. 文件

           

  • 相关阅读:
    明明已经include_once() 但还是报错Class 'XXXXXControllerTOPData' not found
    dell U2515H 2k显示器黑屏问题,dp线问题。
    centos7.4 php5升级到php7
    thinkphp批量插入 更新sql
    查询速度慢了10倍,查询条件类型不对,字符串当做数字类型。
    margin-left:auto;margin-right:auto; 不起作用的原因
    jquery 查找元素,id,class
    php分割url,获取参数query
    阿里云服务器删除日志的方法,查看有哪些大文件
    sql优化 分字段统计查询
  • 原文地址:https://www.cnblogs.com/venicid/p/7967176.html
Copyright © 2011-2022 走看看