使用多个工作者执行Python代码
我正在处理几个很大的文件,使用的是Python代码。因为每次只能处理一个文件,所以等到最后一个文件处理完要花很长时间。因此,我想问一下:有没有办法让多个工作进程同时处理这些文件呢?
这样调用可以吗?:
import annotation as annot # this is a .py-file
import multiprocessing
pool = multiprocessing.Pool(processes=4)
pool.map(annot, "")
这个.py文件使用了for循环等方法来处理所有文件。问题是:我用'top'命令查看所有进程时,只看到一个进程在运行这个.py文件。所以...我怀疑我这样使用多进程是不对的,对吧?谢谢大家的帮助!:)
4 个回答
是的,这个是可以做到的。你可以看看 threading模块 和 multiprocessing模块。这两个模块都能让你同时运行Python代码。不过,关于threading模块有一点需要注意,因为Python的实现方式(如果你对细节感兴趣,可以搜索“python GIL”),所以即使你有多个CPU核心,实际上一次只能有一个线程在执行。这和我们其他语言的线程实现不同,在那些语言里,每个线程可以同时运行,各自使用不同的核心。由于这个限制,如果你想同时进行一些需要大量计算的操作,使用multiprocessing模块会有更好的性能。
我的回答虽然不是纯粹的Python解决方案,但我认为这是针对你问题的最佳方法。
这个方法只适用于Unix系统(比如OS X、Linux等)。
我经常做这样的事情,而且我非常喜欢GNU Parallel。你可以看看这个链接,里面有GNU Parallel开发者的介绍。你可能需要先安装它,但这绝对值得。
这里有个简单的例子。假设你有一个叫做processFiles.py
的Python脚本:
#!/usr/bin/python
#
# Script to print out file name
#
fileName = sys.argv[0] # command line argument
print( fileName ) # adapt for python 2.7 if you need to
要让这个文件可以执行:
chmod +x processFiles.py
假设你所有的大文件都在largeFileDir
这个文件夹里。然后,如果你想用四个处理器(-P4)同时运行所有文件,可以在命令行输入:
$ parallel -P4 processFiles.py ::: $(ls largeFileDir/*)
这将输出
file1
file3
file7
file2
...
输出的结果可能不是按顺序的,因为每个线程都是独立并行运行的。要把这个方法应用到你的处理过程中,只需把你的文件处理脚本放进去,而不是傻傻地只打印文件内容到屏幕上。
在你的情况下,这种方法比使用线程更好,因为每个文件处理任务都会有自己的Python解释器实例。由于每个文件都是独立处理的(听起来是这样),使用线程就显得有些多余了。根据我的经验,这种方法是并行化你描述的过程最有效的方式。
还有一个叫做全局解释器锁的东西,我不是很理解,但在尝试用Python内置功能进行超线程时,它让我很头疼。所以我建议,如果你不需要使用线程,就不要用。相反,按照我推荐的方式,启动独立的Python进程。
没错。可以使用 multiprocessing.Pool。
import multiprocessing
pool = multiprocessing.Pool(processes=<pool size>)
result = pool.map(<your function>, <file list>)