通过管道传递大型数组时,Python多处理卡住

时间:2019-01-04 16:48:19

标签: python multiprocessing pipe

我正在python中使用多重处理,并尝试通过管道将大型numpy数组传递给子进程。它适用于较小的数组,但可挂在较大的数组上而不会返回错误。

我相信管道已被阻塞并且已经阅读了一些有关它的信息,但是无法弄清楚如何解决该问题。

def f2(conn, x):
    conn.start()
    data = conn.recv()
    conn.join()

    print(data)
    do_something(x)

    conn.close()

if __name__ == '__main__':
    data_input = read_data()    # large numpy array
    parent_conn, child_conn = Pipe()

    p = multiprocessing.Pool(processes=8)      
    func = partial(f2, child_conn)

    parent_conn.send(data_input)
    parent_conn.close()

    result = p.map(func, processes)

    p.close()
    p.join()

1 个答案:

答案 0 :(得分:2)

忽略此代码中的所有其他问题(您没有x传递给map,没有使用x f2接收,将Pool.mapPipe混合通常是错误的操作),您的最终问题是在可以读取工作进程之前 执行阻塞的send调用从它。

假设您确实想将mapPipe混合使用,解决方案是在开始map之前 异步启动send,因此父母尝试写Pipe时,另一面还有东西可以读取:

if __name__ == '__main__':
    data_input = read_data()    # large numpy array
    parent_conn, child_conn = Pipe()

    # Use with to avoid needing to explicitly close/join
    with multiprocessing.Pool(processes=8) as p:
        func = partial(f2, child_conn)

        # Launch async map to ensure workers are running
        future = p.map_async(func, x)

        # Can perform blocking send as workers will consume as you send
        parent_conn.send(data_input)
        parent_conn.close()

        # Now you can wait on the map to complete
        result = future.get()

如前所述,由于x的问题,该代码将无法运行,即使存在Pipe文档也明确警告不要使用两个不同的进程同时从Pipe中读取。

如果您想在一个工作程序中批量处理数据,则只需使用ProcessPipe,就像这样:

def f2(conn):
    data = conn.recv()
    conn.close()
    print(data)

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()

    proc = multiprocessing.Process(target=f2, args=(child_conn,))
    proc.start()

    data_input = read_data()    # large numpy array
    parent_conn.send(data_input)
    parent_conn.close()

    proc.join()

如果要跨多个工作人员分别处理每个元素,则只需使用Poolmap

def f2(x):
    print(x)

if __name__ == '__main__':
    data_input = read_data()    # large numpy array
    with multiprocessing.Pool(processes=8) as p:   
        result = p.map(f2, data_input)