如何从控制台使用多处理库(使用 map_async)启动 python 脚本

How to start a python script using the multiprocessing library (with map_async) from the console

对于这个相当长的问题,我深表歉意,但是,由于这是我在 Whosebug 上提出的第一个问题,我想详细描述我的问题和我已经尝试过的方法。 我正在对随机过程进行模拟,并认为使用多处理来提高模拟速度是个好主意。由于各个进程不需要彼此共享信息,这实际上是多处理的一个简单应用——不幸的是,我很难从控制台调用我的脚本。 我的测试函数代码如下所示:

#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 脚本。在这里我得到了一些意想不到的结果。 我在 Mac Book Pro iOS 10.15.7 和工作站 Ubuntu 18.04.5 上尝试了以下控制台输入:python myscript.pypython -c "from myscript import multi; multi()"。 在每种情况下,我唯一的输出是 Test1Test2,而 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 时出现——但是,我认为对于我的应用程序异步进程更可取。

如果有人能阐明这个谜团(至少对我来说这是个谜团),我将不胜感激。 另外,正如我所说,这是我在 Whosebug 上的第一个问题,所以如果我忘记了相关信息或不小心没有遵循格式指南,我深表歉意。也非常感谢所有帮助我改进未来问题(和答案)的评论或编辑!

您并没有在程序退出之前等待池完成它正在做的事情。

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,块大小参数。)