我无法在此处实施建议:Applying two functions to two lists simultaneously。
我想这是因为模块是由另一个模块导入的,因此我的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)
process_males
和process_females
都是功能。
args_m, args_f
是迭代器
另外,我不需要退货。代理是需要更新的类实例。
答案 0 :(得分:5)
您需要保护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)
<强> main.py:强>
import some_module
if __name__ == "__main__":
some_module.do_stuff()
在您的真实代码中,您可能希望传递一些参数或从do_stuff
获取返回值(也应该给出一个比我在本例中使用的通用名称更具描述性的名称)。
答案 1 :(得分:3)
if __name__ == '__main__':
的想法是避免无限的过程产生。
当挑选主脚本中定义的函数时,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()