day9-进程间数据交互及共享
进程间数据通信的实现方法
2.Pipe()
Pipe()函数返回一对由管道连接的连接对象,代表了pipe的两端,默认情况下为双工(双向),每个对象都有send()和recv()方法。
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello']) #发送数据
print(conn.recv()) #接收数据
conn.close()
if __name__ == '__main__':
# 生成一个管道对象
parent_conn, child_conn = Pipe() #包含2个返回对象(父连接,子连接)
p = Process(target=f, args=(child_conn,)) #生成一个子进程对象
p.start() #启动子进程
print(parent_conn.recv()) #在主进程的父连接接收数据
parent_conn.send("hello world") 发送数据
p.join()
#运行输出
[42, None, 'hello']
hello world
区别和小结
pipe用来在两个进程间通信。queue用来在多个进程间实现通信。此两种方法为所有系统多进程通信的基本方法。
以上2个方法通过实现对进程间的数据传递,而不是共享,如果实现和多线程一样对同一份数据进行共享,可以使用下面的方法
共享
Manager()方法返回一个manager对象控制一个服务器进程,该进程持有Python对象,并允许其他进程使用代理来对他们进行操作。
Manager()方法返回的manager将支持的类型:list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Barrier,Queue,Value 和Array。
from multiprocessing import Process, Manager
import os
def f(d, l):
d[os.getpid()] = os.getpid()
l.append(os.getpid())
print(l)
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict() #生成可在多个进程间传递和共享的dict
l = manager.list(range(5)) #生成可在多个进程间传递和共享的list
p_list = [] #存放进程对象的列表
for i in range(10): #启动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)
#运行输出
[0, 1, 2, 3, 4, 22107]
[0, 1, 2, 3, 4, 22107, 22109]
[0, 1, 2, 3, 4, 22107, 22109, 22108]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111, 22112]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111, 22112, 22113]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111, 22112, 22113, 22114]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111, 22112, 22113, 22114, 22115]
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111, 22112, 22113, 22114, 22115, 22116]
{22112: 22112, 22113: 22113, 22114: 22114, 22115: 22115, 22116: 22116, 22107: 22107, 22108: 22108, 22109: 22109, 22110: 22110, 22111: 22111}
[0, 1, 2, 3, 4, 22107, 22109, 22108, 22110, 22111, 22112, 22113, 22114, 22115, 22116]
Process finished with exit code 0
解析:这里不像线程在对同一份数据操作是需要加锁,manager()方法内部默认已经加锁了。

浙公网安备 33010602011771号