2012-03-30 52 views
1

我正在研究工作者的multiprocessing.Pool,试图用某种状态初始化工作人员。该池可以进行可调用,初始化,但不会传递对已初始化的工作者的引用。我见过的几个例子利用它调用全局变量,这看起来真的很讨厌。在python多处理工作池中初始化的使用

是否有任何好方法使用multiprocessing.Pool初始化工人状态?

编辑:举个例子:

我有工人,每个做一些相对昂贵的初始化(绑定到套接字),我不希望有做每一次。我可以手动初始化套接字,然后在分配工作时传递它们,但跨进程共享文件描述符非常复杂,如果不是不可能的话。所以我每次想处理请求时都必须初始化和绑定。

+1

我有点不清楚为什么你的初始化函数需要对工作者的引用,也许你可以提供一个稍微更具体但最简单的例子,你正在尝试做什么。 – mgilson 2012-03-30 14:11:53

+0

您知道有没有办法告诉*哪个* worker将被分配给特定的函数调用?那么为什么不简单在函数参数中包含该状态呢? – 2012-03-30 14:16:27

回答

1

从技术上讲,正确的做法是将初始化函数的结果作为参数传递给worker所执行的每个函数。

在这种情况下,确实具有全局变量是很好也是安全的,因为通过构建它们可以使私人对象生活在不同过程的不同领域。

我的一般建议是用一种健全的reentrant编程风格构建函数,并在利用multiprocessing功能时允许全局变量。

保持你的榜样,下面send功能需要一些背景(在这种情况下,插座):

def send(socket, data): 
    pass # ... your code here 
    return dust 

初始化代码和由工人执行的基本代码将依赖于全局变量方便。

socket = None 
def init(address, port): 
    global socket 
    socket = magic(address, port) 

def job(data): 
    global socket 
    assert socket is not None 
    return send(socket, data) 

pool = multithreading.Pool(N, init, [address, port]) 
pool.map(job, ['foo', 'bar', 'baz']) 

通过这种方式它变得简单而自然地测试它没有多处理对其进行编码。您可以将您的全局状态视为完全安全的上下文胶囊。

为了方便起见,请记住multiprocessing不擅长发送复杂数据(例如回调)。最好的方法是发送简单的数据(字符串,列表,字典,collections.namedtuple ...),并重新构建工作端的复杂数据结构(使用初始化函数)。