zoukankan      html  css  js  c++  java
  • 生产者消费者模型

    一、什么是生产者消费者模型

      生产者消费者模型就是通过一个容器解决它们之间的强耦合问题,生产者与消费者之间依靠阻塞队列进行通讯,生产者与消费者之间不直接通讯,这样平衡了二者之间的处理能力,这里使用了进程、线程以及生成器实现了生产者消费者模型。

      在进程中分别开启了生产者和消费者的进程,它们之间的通讯依赖进程中的队列Queue来实现的。在线程中分别开启了生产者和消费者线程,它们之间的通讯依赖queue中的Queue完成通讯。协程的使用生成器简单的实现。

      使用进程的方式会耗费大量cpu的资源(包括进程的创建、切换、销毁);线程的方式相比进程来讲切换会较少损耗cpu的资源;协程的方式理论上来讲cpu的利用率达到100%,所以协程应该是较为理想的选择。

    二、使用进程实现生产者消费者模型

    from multiprocessing import Process
    from multiprocessing import Queue
    
    
    def producer(q, name):
    
        # 生产者生产20个数据
        for i in range(20):
            q.put(str(i))
            print("%s生产第%s个" % (name, i))
    
    
    def consumer(q, name):
        while True:
            # 从队列中获取数据
            data = q.get()
            if data:
                print("%s消费第%s个" % (name, data))
            else:
                break
    
    
    if __name__ == '__main__':
        q = Queue()
        # 创建10个生产者
        p_pro_list = []
        for i in range(10):
            p_pro = Process(target=producer, args=(q, "生产者%s" % i))
            p_pro_list.append(p_pro)
            p_pro.start()
        # 等待所有的生产进程结束
        for j in p_pro_list:
            j.join()
        # 然后再q中加入结束标示,用于消费者判断队列中是否还有数据,有多少个生产者加入多少个None
        for k in p_pro_list:
            q.put(None)
    
        # 创建5个消费者
        p_con_list = []
        for i in range(5):
            p_con = Process(target=consumer, args=(q, "消费者%s" % i))
            p_con_list.append(p_con)
            p_con.start()
    
        for j in p_con_list:
            j.join()

    三、使用线程实现生产者消费者模型

    import threading
    from queue import Queue
    
    
    def producer(q, name):
        for item in range(20):
            q.put(item)
            print("%s-%s" % (name, item))
    
    
    def consumer(q, name):
        while True:
            item = q.get()
            if item is None:
                break
            print("%s-%s" % (name, item))
            q.task_done()  # 任务完成后向队列发送一个讯号通知一下
    
    
    if __name__ == '__main__':
        q = Queue()
        # 等待消费者消费q中的产品,与task_done搭配使用
        q.join()
        # 生产者生产产品
        t_pro = threading.Thread(target=producer, args=(q, '生产者生产'))
        t_pro.start()
    
        # 消费者消费产品
        t_con = threading.Thread(target=consumer, args=(q, '消费者消费'))
        t_con.start()

    四、使用线程实现生产者消费者模型

    协程的运行是由程序员控制而非操作系统,所以可以通过yield进行简单的实现。

    import time
    import random
    
    
    def consumer():
        while True:
            item = yield
            print("消费%s" % item)
    
    
    def producer():
        # 第一次调用生成器时,使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的。
        c.send(None)  # 相当于c.next()激活生成器
        while True:
            time.sleep(1)
            item = random.randint(1, 50)
            print("生产%s" % item)
            # 进入生成器函数,此时将item赋值给yield并且传回。相当于把item赋值给consumer中的item。
            c.send(item)
    
    
    if __name__ == '__main__':
        # 消费者生成器
        c = consumer()
        producer()
  • 相关阅读:
    349. 两个数组的交集
    383. 赎金信
    242. 有效的字母异位词
    844. 比较含退格的字符串
    904. 水果成篮
    剑指offer(9)变态跳台阶
    剑指offer(8)跳台阶
    剑指offer(7)斐波那契数列
    剑指offer(6)旋转数组的最小数字
    剑指offer(5)用两个栈实现队列
  • 原文地址:https://www.cnblogs.com/shenjianping/p/11685783.html
Copyright © 2011-2022 走看看