python子进程管道无缓冲行为

时间:2016-07-18 08:51:10

标签: python pipe subprocess buffer

我有下面的代码来读取子进程中的数据,因为它生成并写入文件。

from subprocess import Popen, PIPE
proc = Popen('..some_shell_command..', shell=True, stdout=PIPE)
fd = open("/tmp/procout", "wb")
while True:
    data = proc.stdout.read(1024)
    if len(data) == 0:
        break
    fd.write(data)
fd.close()

'Popen'默认bufsize为0 =>无缓冲。如果出于某种原因,写入文件操作会遇到巨大的延迟,会发生什么?

  • 假设子进程应该生成500GB的数据,那么所有这些数据是否都存储在内存中,直到父进程读取它们为止? (OR)
  • 在将下一个1024字节写入stdout之前,子进程是否会等待父进程读取1024字节的数据? (OR)
  • 在OS管道缓冲区被填满后子进程是否会等待,一旦父进程读取,子进程将再次继续写入? (OR)
  • ...

1 个答案:

答案 0 :(得分:1)

回答你的问题:

  • 不,它不会存储在内存中。超过write限制(cat / proc / sys / fs / pipe-max-size)后,子进程将停留pipe-max-size操作;
  • 子进程在写入之前会写入大约1M,直到父进程读取数据块。在这个子进程之后,将按顺序写入下一个1024字节的顺序;
  • 是的,在阻止IO的情况下,当调用write系统调用时,操作系统将阻止该进程。如果是非阻塞IO,我希望write系统调用将返回EAGAIN或其他特定于系统的错误。

实际上,在调用write系统调用时,应用程序将停滞不前,等待管道缓冲区可用。它并不意味着它会挂起。例如,如果一个应用程序实现某种内部队列并且它有多个线程,它可以继续工作并将任何数据添加到它的队列,而写出线程将等待对于缓冲区。