Python 使用多处理工作人员池

Python 使用多处理工作人员池,python,multiprocessing,Python,Multiprocessing,我编写了以下代码,使我的第二个懒惰的CPU核心工作。代码的基本功能是首先在目录层次结构中找到所需的“sea”文件,然后执行一组外部脚本来处理这些二进制“sea”文件,以生成50到100个文本和二进制文件。正如问题的标题所示,以并行方式提高处理速度 这个问题源于我们在名为“”的IPython用户列表上进行的长时间讨论。从我对IPython并行处理功能的实验开始 问题是我无法正确运行此代码。如果包含“sea”文件的文件夹仅包含“sea”文件,则脚本将在不完全执行外部脚本运行的情况下完成其执行。(假设

我编写了以下代码,使我的第二个懒惰的CPU核心工作。代码的基本功能是首先在目录层次结构中找到所需的“sea”文件,然后执行一组外部脚本来处理这些二进制“sea”文件,以生成50到100个文本和二进制文件。正如问题的标题所示,以并行方式提高处理速度

这个问题源于我们在名为“”的IPython用户列表上进行的长时间讨论。从我对IPython并行处理功能的实验开始

问题是我无法正确运行此代码。如果包含“sea”文件的文件夹仅包含“sea”文件,则脚本将在不完全执行外部脚本运行的情况下完成其执行。(假设我有30-50个外部脚本要运行,但我的启用多处理的脚本只有在执行这些外部脚本链中的第一个脚本后才会耗尽。)有趣的是,如果我在已处理的文件夹上运行此脚本(即“sea”文件已预处理,且输出文件已在该文件夹中),则它会运行,但是这一次,我得到了大约2.4到2.7倍的线性处理时间的加速。由于我的笔记本电脑中只有一个2.5GHz的核心处理器,所以这并不是我所期望的。虽然我有一个CUDA驱动的GPU,但它与我当前的并行计算斗争无关:)

你认为这个问题的根源是什么

感谢您的所有意见和建议

#!/usr/bin/env python

from multiprocessing import Pool
from subprocess import call
import os


def find_sea_files():

   file_list, path_list = [], []
   init = os.getcwd()

   for root, dirs, files in os.walk('.'):
      dirs.sort()
      for file in files:
          if file.endswith('.sea'):
              file_list.append(file)
              os.chdir(root)
              path_list.append(os.getcwd())
              os.chdir(init)

   return file_list, path_list


def process_all(pf):
   os.chdir(pf[0])
   call(['postprocessing_saudi', pf[1]])


if __name__ == '__main__':
   pool = Pool(processes=2)              # start 2 worker processes
   files, paths = find_sea_files()
   pathfile = [[paths[i],files[i]] for i in range(len(files))]
   pool.map(process_all, pathfile)

我能想到几件事:

1) 你把路径文件打印出来了吗?您确定它们都正确生成了吗

a) 我问你,因为你的os.walk有点有趣;dirs.sort()应该是可以的,但似乎没有必要。通常不应使用os.chdir();恢复应该是正常的,但一般来说,您应该只是在init后面加上root

2) 我见过python2.6上的多处理在从池中生成子进程时遇到问题。(我特别让一个脚本使用多处理生成子进程。这些子进程无法正确使用多处理(池被锁定))。试试python2.5 w/mulitprocessing backport

3) 试试cloud.mp模块(它包装了多处理,但处理池的方式有点不同),看看是否有效

你会的

cloud.mp.join(cloud.mp.map(process_all, pathfile))

(免责声明:我是PiCloud的开发者之一)

我首先要对worker进程的运行情况有一个更好的感觉。如果需要,多处理模块会为其子进程提供日志记录。由于您简化了代码以缩小问题的范围,因此我只需使用一些打印语句进行调试,如下所示(或者您可以预打印pf数组):


我用2.6.4实现的Python版本。

1)是的,路径都是正确的。我使用IPython的并行处理功能测试相同的路径,主脚本遍历文件夹并正确执行提到脚本的链接,以完全后处理sea文件。a) sort()是我的Fedora文件系统(ext4)的一种变通方法。没有它,os.walk()可以任意访问文件夹。2) 我来看看2.5。现在我用的是2.6.0,谢谢你的建议。我将尝试一下,但是我倾向于不为其他人添加外部要求来轻松执行脚本。脚本访问第一个目录,在不启动外部处理过程的情况下,脚本转到第二个目录,并尝试从其中处理第一个文件[gsever@ccn合作伙伴]$python proall3.py PID:10723脚本目录:/home/gsever/Desktop/partest/20090317_131342/后处理脚本:09_03_17_13_13_42.sea PID:10724脚本目录:/home/gsever/Desktop/partest/20090318_075533/后处理脚本:09_03_18_07_55_33.sea处理09_03_18_07_55_33.sea文件。。。。。。。。。。。。。。。。。。。。。。。正在处理09_03_17_13_13_42.sea文件。。。。。。。。。。。。。。。。。。。。。。。DoneAgain执行失败,甚至没有在每个sea文件上正确应用外部脚本链。我仍然认为这个问题与Python的多处理模块有关。我很高兴听到更多的评论来找出确切的问题。当我尝试调用作为后处理的一部分的子脚本(即process_raw and execute)时,我没有调用顶级外部脚本,而是得到一个神秘的错误:下面只是错误的一部分。如图所示,IDL执行混乱,无法获得正确的结果。[gsever@ccnpartest]$python proall3.py PID:17722 PID:17723 IDL版本7.1(linux x86 m32)。(c) 2009年,ITT可视信息解决方案IDL 7.1版(linux x86 m32)。(c) 2009年,ITT Visual Information Solutions%无法获取文件状态。单位:0,文件:错误的文件描述符

def process_all(pf):
   print "PID: ", os.getpid()
   print "Script Dir: ", pf[0]
   print "Script: ", pf[1]
   os.chdir(pf[0])
   call(['postprocessing_saudi', pf[1]])


if __name__ == '__main__':
   pool = Pool(processes=2)
   files, paths = find_sea_files()
   pathfile = [[paths[i],files[i]] for i in range(len(files))]
   pool.map(process_all, pathfile, 1) # Ensure the chunk size is 1
   pool.close()
   pool.join()