2014-05-01 70 views
1

我目前使用多处理函数来分析大约10个文件。Python多重处理不等待

但是,我只想每次运行5个进程。

当我试图实现这个,它不起作用。创建更多的流程,然后创建我指定的编号。有没有一种方法可以轻松地将进程数限制为5? (Windows 7/Python 2.7)

编辑: 恐怕您的解决方案仍然无法正常工作。我会尽量在这里发布更多细节;

主要的python文件;

import python1 
import python2 
import multiprocessing 

# parallel = [fname1, fname2, fname3, fname4, fname5, fname6, fname7, fname8, fname9, fname10] 
if name == '__main__': 
    pool = multiprocessing.Pool(processes=max(len(parallel), 5)) 
    print pool.map(python1.worker, parallel) 

Python1文件;

import os 
import time 
import subprocess 

def worker(sample): 
    command = 'perl '+sample[1].split('data_')[0]+'methods_FastQC\\fastqc '+sample[1]+'\\'+sample[0]+'\\'+sample[0]+' --outdir='+sample[1]+'\\_IlluminaResults\\_fastqcAnalysis' 
    subprocess.call(command) 
    return sample 

12个文件的返回语句会在所有打开的perl模块关闭时返回。还打开了12个perl shell,而不是最大的5个。(Image;你可以清楚地看到返回语句在perl命令还没有完成之前回来,并且有超过5个进程http://oi57.tinypic.com/126a8ht.jpg

回答

0

我不'不知道为什么这是一个秘密什么不发生,发生了什么。

并提供一个SSCCE意味着一个实际运行的程序。 (有一个看看worker()功能,例如,它得到它从未使用过file参数,并使用它无处定义的command变量)。

但我认为这是你的fileX只是文件中的点名字和他们被试图执行。

你的函数改为

def worker(filename): 
    command = "echo X " + filename + " Y" 
    os.system(command) 

,它应该工作的罚款。 (请注意,我为了不隐藏内置的名字改为filefilename

BTW,而不是os.system()你应该使用subprocess模块。

在这种情况下,你可以做

import subprocess 

def worker(filename): 
    command = ["echo", "X", filename, "Y"] 
    subprocess.call(command) 

这也应该这样做。

正如文体备注:

pool = multiprocessing.Pool(processes=max(len(parallel), 5)) 

更简单,做同样的。


您的编辑现在使问题更加清晰。

看来,由于未知的原因,你的Perl程序退出的时间比他们真正完成的时间早。我不知道为什么会发生这种情况 - 也许他们会自行分叉并立即退出。或者是由于窗户及其怪异。

只要多处理池注意到子进程声称完成,就可以启动另一个子进程。

所以正确的方法是找出perl程序不按预期工作的原因。

+0

您的方法不适合我。我在我的主要问题中发布了更多的细节。 (也许我应该提到,我导入了其他python文件,对此表示歉意) – user3589561

0

我在Linux下用python-2.7试过下面的代码,它没有声明。一次只创建5个进程。

import os 
import multiprocessing 
import psutil 
from functools import partial 

def worker(pid, filename): 
# assert len(psutil.Process(pid).children(recursive=True)) == 5 # for psutil-2.x 
    assert len(psutil.Process(pid).get_children(recursive=True)) == 5 
    print(filename) 

parallel = range(0, 15) 

if __name__ == '__main__': 
# with multiprocessing.Pool(processes=5) as pool: # if you use python-3 
    pool = multiprocessing.Pool(processes=min(len(parallel), 5)) 
    pool.map(partial(worker, os.getpid()), parallel) 

当然,如果你使用使用os.system()的工人函数中,它会创建额外的进程和进程树的样子(使用使用os.system(“睡眠1”)这里)

\_ python2.7 ./test02.py 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
     \_ sh -c sleep 1 
      \_ sleep 1 
+0

您的方法对我无效。我在我的主要问题中发布了更多的细节。 (也许我应该提到我导入了其他python文件,对此表示歉意) – user3589561

+0

它本身不是'我的方法'。这就是多处理的工作原理。 不用你的perl脚本试试这段代码。如果它工作,你的问题来自perl脚本创建分离子流程。 – ticapix