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()
函数的正确方法,因此可以通过分叉子进程访问它。基本上它是一个共享的数据,我只想检索一次,因为它是对数据库的昂贵调用,我想让它可以被进程访问。
非常感谢任何帮助,谢谢。
答案 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
为空,这就是您真正想要发生的事情。