IPC
IPC指的是进程间通讯
进程是在相互独立的内存中运行的,所以当一个进程需要使用另一个进程的数据时就要使用IPC
共享内存
1.Manager类
Manager提供很多数据结构 list dict等等
Manager所创建出来的数据结构,具备进程间共享的特点
def task(date,lock): lock.acquire() # num=date['num'] time.sleep(0.1) 由于Manager创建的一些数据结构是不带锁的 可能会出现问题,所 date['num']-=1 以这里加了0.1秒的缓冲时间 print(date) lock.release() if __name__ == '__main__': m=Manager() Manager也需要在 if __name__ == '__main__':下调用执行 lock=Lock() date=m.dict({'num':10}) for i in range(10): a=Process(target=task,args=(date,lock)) a.start() time.sleep(2) print(date)
需要强调的是 Manager创建的一些数据结构是不带锁的 可能会出现问题
Queue队列
队列是一种特殊的数据结构,先存储的先取出 就像排队 先进先出
在Queue队列中自动帮我们处理了锁的问题,所以可以不考虑进程间冲突
q = Queue(3) # 创建队列 不指定maxsize 则没有数量限制q.put("abc") # 存储元素q.put("hhh")q.put("kkk") print(q.get())q.put("ooo") # 如果容量已经满了,在调用put时将进入阻塞状态 直到有人从队列中拿走数据有空位置 才会继续执行 print(q.get())# 如果队列已经空了,在调用get时将进入阻塞状态 直到有人从存储了新的数据到队列中 才会继续 print(q.get())print(q.get()) #block 表示是否阻塞 默认是阻塞的 # 当设置为False 并且队列为空时 抛出异常 q.get(block=True,timeout=2) # block 表示是否阻塞 默认是阻塞的 # 当设置为False 并且队列满了时 抛出异常 # q.put("123",block=False,) # timeout 表示阻塞的超时时间 ,超过时间还是没有值或还是没位置则抛出异常 仅在block为True有效
生产者消费者模型
生产者和消费,处理速度不平衡,一方快一方慢,导致一方需要等待另一方
原本,双方是耦合 在一起,消费必须等待生产者生成完毕在开始处理, 反过来
解决的方案:
将双方分开来.一专门负责生成,一方专门负责处理
这样一来数据就不能直接交互了 双方需要一个共同的容器
生产者完成后放入容器,消费者从容器中取出数据
这样就解决了双发能力不平衡的问题,做的快的一方可以继续做,不需要等待另一方
def consuner(q): for i in range(1,11): time.sleep(random.randint(0,2)) print('做出第%s盘菜'%i) q.put('第%s盘菜'%i) def producer(name,q): while True: res=q.get() if not res: time.sleep(5) continue print('吃货%s吃掉了%s'%(name,res)) if __name__ == '__main__': q=Queue(10) c=Process(target=consuner,args=(q,)) p1=Process(target=producer,args=('aaa',q)) p2=Process(target=producer,args=('bbb',q)) c.start() p1.start() p2.start()