• 26、生产者消费者模型


    生产者消费者模型

    一、IPC

    空间复用  中内存隔离开了多个进程直接不能直接交互
    ipc指的就是进程间通讯
    
    几种方式
    1、创建一个共享文件
    	缺点:效率较低
    	优点:理论上交换的数据量可以非常大
    	适用于:交互不频繁,且数据量较大的情况
    2、共享内存
    	缺点:数据量不大
    	优点:效率高
    	适用于:交互频繁,但是数据量小
    3、管道
    	管道也是基于文件的,它是单向的,编程比较复杂
    4、socket
    	编程复杂,更适用于基于网络来交换数据
    

    二、Manager的基本使用

    是一种可以给我们创建进程 同步的容器,但是没有处理安全问题的能力,使用的并不常用,了解即可!
    
    from multiprocessing import Process, Manager
    
    
    def task(data):
        for i in range(100):
            data['num'] -= 1
        print('子 over')
    
    
    if __name__ == '__main__':
        data = {'num': 100}
        m = Manager()  # 创建一个管理器
        syncdict = m.dict(data)  # 让管理器创建一个进程同步的字典
        # 没有给你处理锁
        p = Process(target=task, args=(syncdict,))
        p.start()
    
        p.join()
        print(data)
        print(syncdict)
    

    三、Queue

    Queue翻译为队列 , 是一种特殊的容器,特殊之处在于存取顺序为先进先出
    可以帮我们完成进程间通讯
    
    from multiprocessing import Queue
    
    q = Queue(2)  # 创建队列,并且只能同时存取两个数据
    
    q.put(1)
    q.put(2)
    # put(self , block (布尔值,判断是否为阻塞) , timeout = None(设置时间))
    q.put(3)  # 默认是阻塞的,当容器中没有位置了就阻塞,直到有人从里面取走元素为止
    
    print(q.get())
    print(q.get())
    print(q.get())  # 默认是阻塞的,当容器中没有位置了就阻塞,直到有人存入元素为止
    
    拓展:栈
    也是一种特殊的容器 特殊在于 存取顺序为先进后出
    
    函数调用栈
    调用函数时 称之为函数入栈 函数执行结束返回值为出栈
    

    四、生产者消费者模型

    模型就是套路 , 就是解决某种固定问题的固定套路

    生产者:泛指产生数据的乙方
    消费者:泛指处理数据的乙方
    
    具体解决方法:
    1、先将双方解开耦合,让不同的进程负责不同的任务
    2、提供一个共享的容器,来平衡双方的能力,之所以用进程队列是因为队列可以在进程间共享
    
    案例:
    
    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()  # 直接终止消费者进程
    
  • 相关阅读:
    python拆包与装包-*args,**kwargs
    mybatis学习4-CRUD操作
    mybatis学习3-入门案例,注解方式
    mybatis学习1-前置,复习Jdbc
    spring框架学习-aop
    spring学习1-第一个spring项目
    spring概述
    idea的一些个人设置
    maven的一些个人设置
    VBA文件对话框的应用(VBA打开文件、VBA选择文件、VBA选择文件夹,VBA遍历文件夹)
  • 原文地址:https://www.cnblogs.com/zhaokunhao/p/14453738.html
Copyright © 2020-2023  润新知