令人困惑的是subprocess.Popen

时间:2012-11-09 15:43:24

标签: python subprocess

这个问题让我很困惑

我只想在18个不同的输入文件上运行1个命令,所以我写的就像

while filenames or running:
  while filenames and len(running) < N_CORES:
    filename = filenames.pop(0)
    print 'Submiting process for %s' % filename
    cmd = COMMAND % dict(filename=filename, localdir=localdir)
    p = subprocess.Popen(cmd, shell=True)
    print 'running:', cmd
    running.append((cmd, p))

  i = 0
  while i < len(running):
    (cmd, p) = running[i]
    ret = p.poll()
    if ret is not None:
        rep = open('Crux.report.%d' % (report_number), 'w')
        rep.write('Command: %s' % cmd)
        print localdir
        print 'done!' 
        report_number += 1
        running.remove((cmd, p))
    else:
        i += 1
  time.sleep(1)

但是当我在3小时后运行它时,所有进程都进入睡眠模式。

但是如果我手动从终端调用命令(对于所有不同的文件),所有这些都是好的。

任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:2)

我假设您要运行18个进程(每个文件一个进程)并行处理N_CORES个进程。

最简单的方法是在这里使用multiprocessing.Pool

import multiprocessing as mp
import subprocess

def process_file(filename):
    try:
        return filename, subprocess.call([cmd, filename], cwd=localdir)
    except OSError:
        return filename, None # failed to start subprocess

if __name__ == "__main__":
    pool = mp.Pool()
    for result in pool.imap_unordered(process_file, filenames):
        # report result here

答案 1 :(得分:1)

不知道你的子流程应该做什么以及它们应该运行多长时间,这里很难给出准确的答案。

我在您的程序中看到的一些问题:

  • 检查i < len(running),同时增加i并从running中删除。
    使用计数器或检查列表是否仍包含元素,但不要同时执行这两个操作。这样你就可以中途退出。
  • 每次进程时,您都会增加i,如果进程已经完成,您可能希望增加。