生产者消费者模型
一、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() # 直接终止消费者进程