如何从控制台使用多处理库(使用 map_async)启动 python 脚本
Posted
技术标签:
【中文标题】如何从控制台使用多处理库(使用 map_async)启动 python 脚本【英文标题】:How to start a python script using the multiprocessing library (with map_async) from the console 【发布时间】:2021-05-08 18:38:09 【问题描述】:对于这个相当长的问题,我很抱歉,但由于这是我在 *** 上的第一个问题,我想彻底地描述我的问题以及我已经尝试过的问题。 我正在模拟随机过程,并认为使用多处理来提高模拟速度是个好主意。由于各个进程不需要相互共享信息,这实际上是多处理的一个微不足道的应用程序——不幸的是,我很难从控制台调用我的脚本。 我的 testfunction 代码如下所示:
#myscript.py
from multiprocessing import Pool
def testFunc (inputs):
print(inputs)
def multi():
print('Test2')
pool = Pool()
pool.map_async(testFunc, range(10))
if __name__ == '__main__':
print('Test1')
multi()
只要我从我的 Spyder IDE 中运行代码,这绝对可以正常工作。作为下一步,我想在我通过 slurm 脚本访问的大学集群上执行我的脚本;因此,我需要能够通过 bash 脚本执行我的 python 脚本。在这里,我得到了一些意想不到的结果。
我在装有 ios 10.15.7 的 Mac Book Pro 和装有 Ubuntu 18.04.5 的工作站上尝试过以下控制台输入:python myscript.py
和 python -c "from myscript import multi; multi()"
。
在每种情况下,我唯一的输出是Test1
和Test2
,而testFunc
似乎从未被调用过。按照这个答案Using python multiprocessing Pool in the terminal and in code modules for Django or Flask,我还尝试了省略if __name__ == '__main__'
并将相关功能导入另一个模块的各种版本。例如我试过`
#myscript.py
from multiprocessing import Pool
def testFunc (inputs):
print(inputs)
pool = Pool()
pool.map_async(testFunc, range(10))
但一切都没有占上风。更让我困惑的是,我现在发现首先打开控制台的 python 解释器只需输入python
,按回车然后执行
from myscript import multi
multi()
在 python 解释器中确实工作。
正如我所说,我对此感到非常困惑,因为我认为这相当于python -c "from myscript import multi; multi()"
,我真的不明白为什么一个有效而另一个无效。为了重现这一成功,我还尝试执行以下 bash 脚本
python - <<'END_SCRIPT'
from multiTest import multi
multi()
END_SCRIPT
但是,唉,这也行不通。
作为最后一次“发现”,我发现所有这些问题仅在使用 map_async
而不仅仅是 map
时出现 - 但是,我认为对于我的应用程序而言,异步进程更可取。
如果有人能解开这个谜团,我将不胜感激(至少对我来说这是一个谜)。 另外,正如我所说,这是我在 *** 上的第一个问题,所以如果我忘记了相关信息或不小心没有遵循格式指南,我深表歉意。非常感谢所有帮助我在未来改进我的问题(和答案)的 cmets 或编辑!
【问题讨论】:
【参考方案1】:在程序退出之前,您无需等待池完成它正在执行的操作。
def multi():
print('Test2')
with Pool() as pool:
result = pool.map_async(testFunc, range(10))
result.wait()
如果子流程处理事物的顺序不相关,我建议
with Pool() as pool:
for result in pool.imap_unordered(testFunc, range(10), 5):
pass
(更改5
,块大小参数,以品尝。)
【讨论】:
哇...感谢您提供非常快速且有用的答案!这确实有效!我仍然对(在我的原始代码中)python -c "from myscript import multi; multi()"
产生与首先使用python
进入 python 解释器然后在解释器中编写 python 代码不同的结果感到困惑。知道为什么这两种方法不同吗?
当您以交互模式进入解释器时,在您输入内容后它会继续运行,并且子进程有时间在它们的主进程退出之前完成它们的工作。如果您使用-c
,就像您刚刚拥有一个包含-c
内容的文件一样。您可以使用-i -c ...
运行命令,然后进入交互模式。以上是关于如何从控制台使用多处理库(使用 map_async)启动 python 脚本的主要内容,如果未能解决你的问题,请参考以下文章
multiprocessing.Pool:map_async 和 imap 有啥区别?