如何在导入的模块中使用multiprocessing.Pool?

B F*_*ado 4 python multiprocessing python-multiprocessing

我无法在这里实现这个建议:同时将两个函数应用于两个列表.

我想这是因为模块是由另一个模块导入的,因此我的Windows会生成多个python进程?

我的问题是:如果没有if,我怎么能使用下面的代码 if __name__ == "__main__":

args_m = [(mortality_men, my_agents, graveyard, families, firms, year, agent) for agent in males]
args_f = [(mortality_women, fertility, year, families, my_agents, graveyard, firms, agent) for agent in females]

with mp.Pool(processes=(mp.cpu_count() - 1)) as p:
    p.map_async(process_males, args_m)
    p.map_async(process_females, args_f)
Run Code Online (Sandbox Code Playgroud)

这两个process_malesprocess_females是fuctions. args_m, args_f是迭代器

另外,我不需要退货.代理是需要更新的类实例.

Blc*_*ght 6

您需要在a中保护多处理代码的原因if __name__ == "__main__"是您不希望它在子进程中再次运行.这可能发生在Windows上,其中解释器需要重新加载其所有状态,因为没有fork系统调用将复制父进程的地址空间.但是你只需要在代码应该在顶级运行的地方使用它,因为你在主脚本中.这不是保护代码的唯一方法.

在您的具体情况下,我认为您应该将multiprocessing代码放在一个函数中.这不会在子进程中运行,只要没有其他任何东西在不应该的时候调用该函数.您的主模块可以导入模块,然后调用该函数(if __name__ == "__main__"可能在块内).

它应该是这样的:

some_module.py:

def process_males(x):
    ...

def process_females(x):
    ...

args_m = [...] # these could be defined inside the function below if that makes more sense
args_f = [...]

def do_stuff():
    with mp.Pool(processes=(mp.cpu_count() - 1)) as p:
        p.map_async(process_males, args_m)
        p.map_async(process_females, args_f)
Run Code Online (Sandbox Code Playgroud)

main.py:

import some_module

if __name__ == "__main__":
    some_module.do_stuff()
Run Code Online (Sandbox Code Playgroud)

在您的真实代码中,您可能希望传递一些参数或从中获取返回值do_stuff(也应该给出一个比我在本例中使用的通用名称更具描述性的名称).


Tho*_*eau 4

的想法if __name__ == '__main__':是避免无限进程产生。

当 pickle 主脚本中定义的函数时,python 必须弄清楚主脚本的哪一部分是函数代码。它基本上会重新运行您的脚本。如果您创建的代码Pool位于同一脚本中并且不受“if main”保护,那么通过尝试导入该函数,您将尝试启动另一个函数,Pool该函数将尝试启动另一个Pool......

因此,您应该将函数定义与实际的主脚本分开:

from multiprocessing import Pool

# define test functions outside main
# so it can be imported withou launching
# new Pool
def test_func():
    pass

if __name__ == '__main__':
    with Pool(4) as p:
        r = p.apply_async(test_func)
        ... do stuff
        result = r.get()
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个答案错过了问题的要点,即“Pool”创建代码应该位于另一个模块中,而不是主要模块中。因此,你不能在它周围放置 `if __name__ == "__main__"` 保护,因为它根本不在主模块中。 (14认同)