进程通信
进程队列Queue:
from multiprocessing import Process,Queue#进程队列
def info(q):
q.put(123)
q.put('huang')
if __name__ == '__main__':
q = Queue()#进程队列
p = Process(target=info,args=(q,))
p.start()
print(q.get())
print(q.get())
这儿不同于之前说的线程队列,线程队列因为在同一个进程里,所以共享进程里的资源,所以队列不用通过参数传过去,而这儿的多进程,不共享资源,所以必须用multiprocessing里的进程队列,而且要通过参数形式传过去。
这儿有一点要说下,进程间通信是很耗资源的,比如将队列q,传给子进程,远不止表面传那么简单,中间其实是将q拷贝一份传过去的,所以进程之间的通信很好资源。
进程管道(Pipe):
from multiprocessing import Process,Pipe
def f(conn):
conn.send([12,{'name':'huang'},'hello'])
response = conn.recv()
print('response',response)
conn.close()
print('q_ID2:',id(conn))
if __name__ == '__main__':
parent_conn,child_conn = Pipe()#双向管道
print('q_ID1:',id(child_conn))
p = Process(target=f,args=(child_conn,))
p.start()
print(parent_conn.recv())
parent_conn.send('你好son')
p.join()
运行结果:
q_ID1: 140549723704848
[12, {‘name’: ‘huang’}, ‘hello’]
response 你好son
q_ID2: 140549723704848
进程共享(Manager):
Queue和Pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。
from multiprocessing import Process,Manager
def f(d,l,n):
d[n] = '1'
d['2'] = 2
d[0.25] = None
l.append(n)
print('son process:',id(d),id(l))
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list(range(5))
print('main process:',id(d),id(l))
p_list = []
for i in range(10):
p = Process(target=f,args=(d,l,i))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l)
运行结果:
main process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
son process: 140550017739912 140549781507320
{1: ‘1’, ‘2’: 2, 0.25: None, 0: ‘1’, 2: ‘1’, 5: ‘1’, 7: ‘1’, 6: ‘1’, 4: ‘1’, 3: ‘1’, 8: ‘1’, 9: ‘1’}
[0, 1, 2, 3, 4, 1, 2, 0, 5, 7, 6, 4, 3, 8, 9]