不同进程间的内存数据是不共享的,要想实现两个进程间的数据交换,可以用下面几种方法:
1. Queues
multiprocess_queue.py
from multiprocessing import Process, Queue
def run(process_obj):
process_obj.put(['xiaoming',12])
if __name__ == '__main__':
q = Queue() #创建进程的Queue,注意和线程queue区分开来
#q.put(["xiaofang"])
p = Process(target=run, args=(q,))
p.start()
print(q.get())
p.join()
auto@auto-vm:~/docker_share/test/python$ python multiprocess_queue.py
['xiaoming', 12]
2.Pipes
multiprocess_pipe.py
from multiprocessing import Process, Pipe
def run(conn):
conn.send("send data")
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=run, args=(child_conn,))
p.start()
print(parent_conn.recv())
p.join()
auto@auto-vm:~/docker_share/test/python$ python multiprocess_pipe.py
send data
3. Managers
上面两种方式只是实现了进程间数据的传递,还没有实现数据的共享。表面上是进程间共享一份数据,实际上是每个进程会赋值一份数据,manager里面自己会加锁,所以在代码里不用加锁。
multiprocess_manager.py
from multiprocessing import Process, Manager
import os
def fun(d, l):
d[os.getppid()] = os.getppid()
l.append(os.getppid())
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=fun, args=(d, l))
p.start()
p_list.append(p)
for res in p_list: #等待结果
res.join()
print(d)
print(l)
auto@auto-vm:~/docker_share/test/python$ python multiprocess_manager.py
[0, 1, 2, 3, 4, 18774]
[0, 1, 2, 3, 4, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774]
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774]
{18774: 18774}
[0, 1, 2, 3, 4, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774, 18774]
4. 进程锁
进程间内存本来就是独立的,数据不能互相访问,为什么还要设置进程锁?原因是多个进程在打印输出时会共享屏幕输出,为了防止屏幕显示错误,才引用进程锁。
multiprocess_lock.py
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
auto@auto-vm:~/docker_share/test/python$ python multiprocess_lock.py
hello world 0
hello world 1
hello world 3
hello world 4
hello world 5
hello world 7
hello world 8
hello world 2
hello world 6
hello world 9
5. 进程池Pool
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止
from multiprocessing import Process, Pool
import time
def Foo(i):
time.sleep(2)
return i+100
def Bar(args):
print("callback function", args)
if __name__ == '__main__':
pool = Pool(processes=5)#允许进程池里同时放入5个进程使用CPU去运行
for i in range(10):
#pool.apply(func=Foo,args=(i,)) #并行,一次输出5个
#pool.apply_async(func=Foo,args=(i,),callback=Bar)) #并行,一次输出5个
pool.apply(func=Foo, args=(i,))#串行,一条条的输出
pool.close()
#pool.join() #进程池中进程执行完毕后再关闭,如果注释,则程序直接关闭