【问题标题】:python pipe limited to 196608 ( 65536*3 ) with subprocess.Popen()python 管道限制为 196608 ( 65536*3 ) 与 subprocess.Popen()
【发布时间】:2018-12-22 13:06:31
【问题描述】:

我有这个函数call_external_command 如果 len(data) 196608 它永远挂起。

def call_external_command(command, data):
    try:
        p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
        p.stdin.write(data)
    except:
        return None
    else:
        return p.communicate()[0]

为什么有这个限制?以及如何解决?

【问题讨论】:

标签: python pipe


【解决方案1】:

哦,太好了!事实上,我们必须使用 communicate() 而不是 stdin.write()

def call_external_command(command, data):
    p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
    return p.communicate(data)[0]

【讨论】:

    【解决方案2】:

    正如 oyu 自己发现的那样,.communicate() 会处理这个问题。

    您观察的原因如下:

    • 两个管道连接您的程序和子进程,即其标准输入和标准输出。
    • 根据操作系统,这些管道中的每一个都具有 65536 字节的缓冲区大小。
    • 此外,根据程序及其功能,它还会读取 65536 个字节并写出一些数据。

    因此,如果您写入 196608 个字节,则前 65536 个字节将被发送到标准输入,由程序读取并(例如,如果是 cat)输出到标准输出管道。第二个 65536 字节被放入标准输入,由程序读取并尝试写入标准输出,但由于标准输出已满,它在那里阻塞。第三个 65536 字节写入标准输入。对于每个多余的字节,写入块,因为标准输入也已满。

    解决方案就像你写的那样:让.communicate() 处理整个事情。它已为这种情况做好准备并根据操作系统使用线程、轮询或选择调用来处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      相关资源
      最近更新 更多