具有大对象的Python多处理管道将挂起

时间:2018-07-01 16:26:10

标签: python dictionary multiprocessing pipe

下面有一个简单的代码片段演示了该问题。

import (
    "github.com/DataDog/datadog-go/statsd"
    "log"
)

func main() {
    // Create the client
    c, err := statsd.New("127.0.0.1:8125")
    if err != nil {
        log.Fatal(err)
    }
    // Prefix every metric with the app name
    c.Namespace = "myapp."
    // Count two events
    err = c.Count("my_counter", 2, nil, 1)
    if err != nil {
        log.Fatal(err)
    }
    // Close the client
    err = c.Close()
    if err != nil {
        log.Fatal(err)
    }
}

上面的方法工作正常,对于我的目的来说足够快,在那里没有问题。但是,如果我将大小设置为5000,它会无限期地挂起:

from multiprocessing import Pipe
import time

recv_end, send_end = Pipe(duplex=False)
d = {'word'+str(elem): elem for elem in range(3000)}

start_time = time.time()
send_end.send(d)
print('--- %s seconds ---' % (time.time()-start_time))

Pipe是否有尺寸限制,或者这是不可复制的问题?如果使尺寸更大怎么办?如果存在大小限制,那么避免此问题并通过Pipe通过大型字典发送的最佳方法是什么?预先感谢!

1 个答案:

答案 0 :(得分:0)

发生此问题是因为Pipe.send()是一个阻止呼叫,它等待被接收。阅读更多here。 要使其正常工作,您可以像下面的代码那样创建过程:

#!/usr/bin/env python
from multiprocessing import Pipe, Process
import time
import sys


def foo(conn):
    d = {'word'+str(elem): elem for elem in range(5000)}  # changed to 5000
    conn.send(d)
    conn.close()


recv_end, send_end = Pipe(duplex=False)
p = Process(target=foo, args=(send_end, ))
p.start()

start_time = time.time()
recv_end.recv()  # Try to comment and you will see that it waits for being received
p.join()
print('--- %s seconds ---' % (time.time()-start_time))