【问题标题】:Multi processing subprocess多处理子流程
【发布时间】:2011-04-01 15:25:18
【问题描述】:

我是 python 的子进程模块的新手,目前我的实现不是多处理的。

import subprocess,shlex
    def forcedParsing(fname):

        cmd = 'strings "%s"' % (fname)
        #print cmd
        args= shlex.split(cmd)
        try:
            sp = subprocess.Popen( args, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE )
            out, err = sp.communicate()
        except OSError:
            print "Error no %s  Message %s" % (OSError.errno,OSError.message)
            pass

        if sp.returncode== 0:
            #print "Processed %s" %fname
            return out

    res=[]
    for f in file_list: res.append(forcedParsing(f))

我的问题:

  1. sp.communicate 是个好方法吗?我应该使用民意调查吗?

    如果我使用 poll,我需要一个单独的进程来监控进程是否正确完成?

  2. 我应该在for 循环中分叉吗?

【问题讨论】:

    标签: python multithreading process subprocess fork


    【解决方案1】:

    1) subprocess.communicate() 似乎是您尝试做的正确选择。而且您不需要轮询进程,communicate() 仅在完成时返回。

    2) 你的意思是分叉来并行化工作?看看multiprocessing (python >= 2.6)。使用子进程运行并行进程当然是可能的,但这是一项相当大的工作,你不能只调用communicate(),它是阻塞的。

    关于您的代码:

    cmd = 'strings "%s"' % (fname)
    args= shlex.split(cmd)
    

    为什么不简单呢?

    args = ["strings", fname]
    

    至于这种丑陋的模式:

    res=[]
    for f in file_list: res.append(forcedParsing(f))
    

    您应该尽可能使用列表理解:

    res = [forcedParsing(f) for f in file_list]
    

    【讨论】:

    • 很好的答案,是的,我想使用多处理,但当前的 Debian 稳定版只有 2.5.x,这太糟糕了。我以后可能会换成 gentoo/sabayon。也非常感谢纠正我的语法,这只是示例代码,实际上里面有一些条件语句,所以列表推导是不可能的。如果我在循环中分叉,subprocess.communicate 会阻塞吗? ,那是个坏消息。所以改用民意调查?我只需要程序退出时的输出,而不是一直..
    • 您可以尝试多处理反向端口:code.google.com/p/python-multiprocessing
    【解决方案2】:

    关于问题 2:如果脚本应该在具有多个内核/处理器的系统上运行,则在 for 循环中分叉将大大加快速度。但是,它会消耗更多的内存,并且会给 IO 带来更大的压力。取决于file_list 中的文件数量,某处会有一个最佳位置,但只有在实际目标系统上进行基准测试才能告诉您它在哪里。如果您找到该号码,您可以添加一个 if len(file_list) > <your number>: 和可选的 fork() 'ing [Edit: 而是@tokland 通过multiprocessing 说的,如果它在您的 Python 版本(2.6+)上可用)] 根据每个工作选择最有效的策略。

    在此处阅读有关 Python 分析的信息:http://docs.python.org/library/profile.html

    如果你在 Linux 上,你也可以运行 time: http://linuxmanpages.com/man1/time.1.php

    【讨论】:

    • 好的,我可以限制 ofcoz 的分叉数量。是的。我在 linux 上,文件列表可以达到 10k + 所以可以说,同时 10 个分叉应该没问题(生产服务器将 8 个内核和高达 16 GB 的 DDR3 RAM)。
    【解决方案3】:

    subprocess documentation 中有几个警告建议您使用communicate 来避免进程阻塞问题,因此最好使用它。

    【讨论】:

    • 更正,它不会在多处理模块中阻塞(fork 也可以!)
    猜你喜欢
    • 2014-11-12
    • 1970-01-01
    • 2020-02-27
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多