一:进程间数据交换方法
不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:
Queue,Pipe ,managers
1)Queue,使用方法跟threading里的queue差不多
# -*- coding:utf-8 -*- __author__ = 'shisanjun' from multiprocessing import Process,Queue import threading import queue # def run(q): # q.put([42,None,"hello"]) # # # if __name__=="__main__": # # q=Queue() # p=Process(target=run,args=(q,)) # p.start() # print(q.get()) """ 正常进程间传递,把query当做参数传给子进程 想当于父进程克隆了一份数据给子进程 其他是两个q父进程q序列化保存在某个位置,子进程q在反序列化 """ def f(): q.put([42,None,"hello"]) # if __name__=="__main__": # # q=queue.Queue() # p=threading.Thread(target=f,) # p.start() # print(q.get()) """ 线程共享内存,所以可以访问q """ # if __name__=="__main__": # # q=queue.Queue() # p=Process(target=f,) # p.start() # print(q.get()) """ name 'q' is not defined 主进程和子进程不能共享内存,所以不能用q """ if __name__=="__main__": q=queue.Queue() #线程队列 p=Process(target=f,args=(q,)) p.start() print(q.get()) """ TypeError: can't pickle _thread.lock objects 往线程里面放数据,他没有序列化,往进程里放数据 """
2)Pipe
Pipe()返回的对象代表管的两端。每个连接对象有send()和recv()方法(等等)。请注意,如果两个进程(或线程)试图同时读取或写入管道的同一端,则管道中的数据可能会损坏。当然,同时使用不同管端的过程不会有损坏的危险。
# -*- coding:utf-8 -*- __author__ = 'shisanjun' from multiprocessing import Pipe,Process def f(conn): conn.send([42,None,"hello"]) conn.close() if __name__=="__main__": parent_conn,child_conn=Pipe() #管道两边 p=Process(target=f,args=(child_conn,)) #管道一头 p.start() print("111%s" %parent_conn.recv())#管道另一头 p.join()
3)managers
一个managers返回的对象manager()控制服务器进程持有的Python对象,允许其它进程操控他们使用代理。
A manager returned by Manager()
支持类型 list
, dict
, Namespace
, Lock
, RLock
, Semaphore
, BoundedSemaphore
, Condition
, Event
, Barrier
, Queue
, Value
and Array
.
# -*- coding:utf-8 -*- __author__ = 'shisanjun' from multiprocessing import Process, Manager def f(d, l): d[1] = '1' d['2'] = 2 d[0.25] = None l.append(1) print(l) if __name__ == '__main__': with Manager() as manager: d = manager.dict() l = manager.list(range(5)) p_list = [] for i in range(10): p = Process(target=f, args=(d, l)) p.start() p_list.append(p) for res in p_list: res.join() print(d) print(l)
4)区别
queue,pipe:只适用于多个进程都是源于同一个父进程的情况
manager如果多个进程不是源于同一个父进程
Queue Pipe只是实现进程间数据的传递
Manager实现了进程间数据的共享,即多个进程可以修改同一份数据