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()方法内部默认已经加锁了。

 

posted @ 2017-12-11 23:45  Mr.hu  阅读(230)  评论(0编辑  收藏  举报