• 生产者消费者模型


    生产消费者模型是将消费者的充分处理完生产的数据,并将效率最大化。

    生产者: 泛指产生数据的一方

    消费者: 泛指处理数据的一方

    一、具体的解决方法:

    1、案例:

    ​ 食堂饭店是生产者

    ​ 我们吃饭的人就是消费者

    2、案例分析

    他们之间有什么问题

    ​ 效率低 因为双方的处理速度不同 一个快一个慢 则双方需要相互等待

    1.先将双方解开耦合,让不同的进程负责不同的任务
    2.提供一个共享的容器 来平衡双方的能力,之所用进程队列是因为队列 可以在进程间共享
    案例1:
    from multiprocessing import Process,Queue
    import requests
    import re,os,time,random
    # 生产者任务
    def product(urls,q):
        i = 0
        for url in urls:
            response = requests.get(url)
            text = response.text
            # 将生产完成的数据放入队列中
            time.sleep(random.random())
            q.put(text)
            i += 1
            print(os.getpid(),"生产了第%s个数据" % i)
    
    def customer(q):
        i = 0
        while True:
            text = q.get()
            time.sleep(random.random())
            res = re.findall('src=//(.*?) width', text)
            i += 1
            print(" 第%s个任务获取到%s个img" % (i,len(res)))    
    if __name__ == '__main__':
        urls = [
            "http://www.baidu.com",
            "http://www.baidu.com",
            "http://www.baidu.com",
            "http://www.baidu.com",
        ]
    
        # 创建一个双方能共享的容器
        q = Queue()
    
        # 生产者进程
        p1 = Process(target=product,args=(urls,q))
        p1.start()
    
        # 消费者进程
        c = Process(target=customer,args=(q,))
        c.start()
    
    问题: 消费不知道什么时候结束
    案例进阶:

    joinableQueue 继承自Queue 用法一致,

    增加了join 和taskDone

    join是个阻塞函数 会阻塞直到taskdone的调用次数等于 存入的元素个数 可以用于表示队列任务处理完成

    案例:
    from multiprocessing import Process,JoinableQueue
    import requests
    import re,os,time,random
    
    """
    生产者 负责生产热狗 
    消费者 负责吃热狗  
    
    """
    # 生产者任务
    def product(q,name):
        for i in range(5):
            dog = "%s的热狗%s" % (name,(i + 1))
            time.sleep(random.random())
            print("生产了",dog)
            q.put(dog)
    
    # 吃热狗
    def customer(q):
        while True:
            dog = q.get()
            time.sleep(random.random())
            print("消费了%s" % dog)
            q.task_done() # 标记这个任务处理完成      
    if __name__ == '__main__':
        # 创建一个双方能共享的容器
        q = JoinableQueue()
        # 生产者进程
        p1 = Process(target=product,args=(q,"上海分店"))
        p2 = Process(target=product,args=(q,"北京分店"))
        p1.start()
        p2.start()
        # 消费者进程
        c = Process(target=customer,args=(q,))
        # c.daemon = True # 可以将消费者设置为守护进程 当主进程确认 任务全部完成时 可以随着主进程一起结束
        c.start()
        p1.join()
        p2.join()  # 代码走到这里意味着生产方完成
        q.join() # 意味着队列中的任务都处理完成了
        # 结束所有任务
        c.terminate() # 直接终止消费者进程
        # 如何判定今天的热狗真的吃完了
        # 1.确定生成者任务完成
        # 2.确定生出来的数据已经全部处理完成
    

    redis 消息队列

    MQ 消息队列

    常用来做流量削峰 保证服务不会因为高并发而崩溃

  • 相关阅读:
    List of 3rd Party .NET UI & Reporting Components
    cannot open window service on computer '.' in window application
    CentOS7重新生成 /boot/grub2/grub.cfg
    vmware esxi 查看网卡、Raid卡驱动
    libcmt.lib和msvcrt.lib冲突,原因和解决方法
    C/C++注释规范
    lsof命令查看端口关联的文件
    linux下查看磁盘分区的文件系统格式
    编译linux kernel及制作initrd ( by quqi99 )
    三种虚拟化技术比较
  • 原文地址:https://www.cnblogs.com/chuwanliu/p/11134408.html
Copyright © 2020-2023  润新知