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()  # 直接终止消费者进程
原文地址:https://www.cnblogs.com/zhaokunhao/p/14453738.html