将列表列表传递给多处理.Pool似乎不起作用

时间:2014-05-22 01:03:57

标签: python multiprocessing pool

from multiprocessing import Pool

data_table = None
def init_data_table(my_data_table = [], *args):
    global data_table
    data_table = my_data_table

def process_data(index):
    # create data processor object and run cpu intensive task here
    return str(index) + " " +  data_table[index][0]

def main():
    # call db functions once and get data table from db
    data_table = ...
    pool = Pool(processes = 4, initializer=init_data_table, initargs=(data_table))
    x = pool.map(process_data, range(10))

问题是当我尝试传递data_table并稍后访问它时,它不起作用。我收到这个错误:

IndexError: list index out of range

我不确定这是否是将复杂数据结构(如元组或列表列表)传递到Pool()函数的正确方法,因此可以通过分叉子进程访问它。基本上它是一个共享的数据,我只想检索一次,因为它是对数据库的昂贵调用,我想让它可以被进程访问。

非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:2)

multiprocessing.Pool的文档说明了initializer

  

如果初始化程序不是None,则每个工作进程都会调用   初始化程序(* initargs)启动时。

所以在你的情况下,它正在调用init_data_table(*data_table)。由于*,它将尝试解压缩列表列表,获取每个子列表并将其分配给init_data_table定义中的变量。你已将其定义为

def init_data_table(my_data_table=[], *args):

因此,当Python尝试解压缩时,第一个子列表最终以my_data_table结尾,其余所有结果都以元组结尾,分配给*args。为避免这种情况,您需要在将data_table分配给initargs时将其放入元组中。它实际上看起来像你试图这样做,但你忘了包括尾随逗号:

pool = Pool(processes = 4, initializer=init_data_table, initargs=(data_table,))

然后,Python最终调用init_data_table(*(data_table,)),它将在data_table中解压缩整个my_data_table列表,使*args为空,这就是您真正想要发生的事情。