首页 文章

python子进程管道无缓冲行为

提问于
浏览
0

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

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的数据,那么所有这些数据是否都存储在内存中,直到父进程读取它们为止? (要么)

  • 在将下一个1024字节写入stdout之前,子进程是否会等待父进程读取1024字节的数据? (要么)

  • 在OS管道缓冲区被填满之后子进程是否会等待,一旦父进程读取,子进程将再次继续写入? (要么)

  • ??

1 回答

  • 1

    回答你的问题:

    • 不,它不会存储在内存中 . 超过 pipe-max-size limit(cat / proc / sys / fs / pipe-max-size)后,子进程将停留在 write 操作上;

    • 子进程将在它停滞之前写入大约1M,直到父进程读取数据块 . 在这个子进程之后,将按顺序写入下一个1024字节的顺序;

    • 是的,在阻塞IO的情况下,当调用 write 系统调用时,操作系统将阻止该进程 . 在非阻塞IO的情况下,我希望 write 系统调用将返回EAGAIN或其他系统特定的错误 .

    所以实际上应用程序会在调用 write 系统调用时卡住,等待管道缓冲区可用 . 当写出线程等待缓冲区时,它不会排队 .

相关问题