【问题标题】:Processing lots of data through a pipe with python / popen使用 python / popen 通过管道处理大量数据
【发布时间】:2012-06-27 00:33:15
【问题描述】:

我正在尝试观察一个过程并等待某种模式,比如:

open someFile id=123

然后,在那之后,我想等待

close id=123

我尝试编写脚本如下:

running_procs = [Popen(["process", "and", "options"], stdout=PIPE, stderr=PIPE)]

while running_procs:
    for proc in running_procs:
        retcode = proc.poll()
        if retcode is not None: # Process finished.
            running_procs.remove(proc)
            break
        else:
            while True:
                next_line = proc.stdout.readline()
                if next_line == '' and proc.poll() != None:
                    break
                m = re.search( r'someFile.*id\=([0-9]*)', next_line, re.M|re.I)
                if m:
                  print m.group(1)

但它似乎执行得太慢了。关于处理管道中的大量线路有什么建议吗?有更快的方法吗?

【问题讨论】:

  • 你试过分析它吗? python -m cProfile -s time myscript.py(如果我没记错的话)
  • 当您声称它太慢时,您是说该过程正在快速产生输出但您的读取方法处理管道太慢了吗?
  • “太慢”是指这些行似乎在缓冲,而 python 处理它的速度似乎太慢了。最终成为实际情况的是,正如您在回答中指出的那样,缓冲区大小太高。将其设置为 1 解决了我的问题。

标签: python subprocess pipe popen


【解决方案1】:

在这个特定示例中没有任何内容表明它应该仅仅因为代码而变慢。在您的列表中只有一个进程,它会以尽可能快的速度读取行,因为进程使它们可用。这意味着代码将依赖于子进程刷新其输出并使行可用。但这确实是意料之中的。

由于您将始终逐行阅读,您可能需要在 Popen 中设置 bufsize=1,以确保其始终缓冲行:

Popen(["process"], stdout=PIPE, stderr=PIPE, bufsize=1)

但是,如果您打算运行多个进程,我确实看到了一个问题,正如您正在使用可能的进程列表并从中弹出死进程这一事实所表明的那样。您的循环将一次阻塞一个进程。如果这不是您让进程串行读取的意图,那么这将导致您获取数据的方式变慢。它们并行运行,但只能串行监控。

除此之外,您还必须更详细地说明您认为结果缓慢的原因以及您期望发生的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    相关资源
    最近更新 更多