如何在Python中高效地运行多个子进程?
基本设置:
我正在使用一个Python脚本来自动测试我正在进行的编程项目。在测试中,我会用很多不同的选项运行我的可执行文件,并将结果与之前的运行结果进行比较。因为我大约有60万个不同的测试要运行,所以测试花费的时间相当长。
目前,我把我的脚本分成了两个部分,一个是测试模块,它从任务队列中获取测试,并把结果放到结果队列中;另一个是主模块,它创建任务队列,然后检查结果。这让我可以尝试使用多个测试进程或线程,但到目前为止,这并没有提高测试速度(我是在一台双核电脑上运行的,我本来希望在四核上使用更多的测试进程能更有效)。
在测试模块中,我创建一个命令字符串,然后用
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
来执行它。接着,我从管道中读取结果,并把它放到结果队列中。
问题:
在多核系统上运行大量命令字符串,这种方式是最有效的吗?每次我使用Popen都会创建一个新进程,这似乎会产生不少开销,但我真的想不出更好的方法来做这件事。
(我目前使用的是Python 2.7,如果这有影响的话。)
编辑:
操作系统是Linux。
我启动的子进程是带参数的命令行C可执行文件。
3 个回答
首先,试着用一个空的可执行文件来测量你的测试脚本或方案。这样你就能看到启动这个过程所花的时间和实际测试时间之间的差距。这样我们就有了真实的数据可以参考。
如果你的工作量相对来说比较小,考虑给你的可执行文件添加一个批处理模式(也就是从文件中读取命令行并执行这些命令),这可能是个好主意。这样做可以节省加载和关闭程序所花的时间。而且,这也能帮助你发现内存泄漏的问题。:)
通过把一些东西移出main()函数,这样做其实并不难。
你可以看看 multiprocessing模块,特别是 Pool部分。
这个模块可以让你启动任意数量的进程(默认是和你的CPU核心数一样多)。
最后,我用SWIG工具为我想测试的代码创建了Python的C语言绑定。结果发现,这样做的速度比启动子进程快了好几百倍。