进程间的数据的传递与共享
进程与进程之间是不能像线程那样共享同一个变量的:
import multiprocessing li = [] def Foo(a): li.append(a) print('li = ',li) for i in range(7): t = multiprocessing.Process(target=Foo,args=(77,)) t.start() >>> li = [77] li = [77] li = [77] li = [77] li = [77] li = [77]
创建的7个进程都创建了数据自己的 li 列表。
进程之间的数据共享:
在使用并发设计的时候,尽量避免数据共享,如果真的有需要进行数据传递与共享,multiprocess提供了2种传递数据的方式:
1、Queue:
类似线程中的queue
import multiprocessing def f(q): q.put('abc') # Queue if __name__ == '__main__': q = multiprocessing.Queue() #创建一个线程的Queue p = multiprocessing.Process(target=f,args=(q,)) p.start() p.join() print(q.get()) >>> abc
主进程在创建子进程的时候,会复制一份Queue到子进程中。
2、Pipe:
# 父进程与子进程之间的通信,类似socket def f(conn): conn.send(['I like ice cream', None , 2333]) if __name__ == "__main__": parentConn ,childConn = Pipe() p = multiprocessing.Process(target=f, args=(parentConn,)) p.start() result = childConn.recv() print(result) >>> ['I like ice cream', None, 2333]
进程间的数据共享
1、Shared memory:
Array,Value
数据可以用Value或Array存储在一个共享内存中:
from multiprocessing import Process,Value,Array def fun(num,array): num.value = 3.1415926 for i in range(len(array)): array[i] = -array[i] if __name__ == '__main__': num = Value('d',0.0) array = Array('i',range(10)) p = Process(target=fun, args=(num, array)) p.start() p.join() print(num.value) print(array[:]) >>> 3.1415926 [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
创建num和arr时,“d”和“i”参数由Array模块使用的typecodes创建:“d”表示一个双精度的浮点数,“i”表示一个有符号的整数,这些共享对象将被线程安全的处理。
Array(‘i’, range(10))中的‘i’参数:
‘c’: ctypes.c_char ‘u’: ctypes.c_wchar ‘b’: ctypes.c_byte ‘B’: ctypes.c_ubyte ‘h’: ctypes.c_short ‘H’: ctypes.c_ushort ‘i’: ctypes.c_int ‘I’: ctypes.c_uint ‘l’: ctypes.c_long, ‘L’: ctypes.c_ulong ‘f’: ctypes.c_float ‘d’: ctypes.c_double
2、Server process manager:
Manager
由Manager()返回的manager提供list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier,Queue, Value and Array类型的支持。
from multiprocessing import Process,Manager def f(d,l): d["name"] = "alex" d["age"] = 22 d["Job"] = "python" l.reverse() #将l反转 if __name__ == "__main__": with Manager() as man: d = man.dict() l = man.list(range(10)) p = Process(target=f,args=(d,l)) p.start() p.join() print(d) print(l) >>>
{'age': 22, 'name': 'alex', 'Job': 'python'}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]