【问题标题】:python subprocess pipe unbuffered behaviourpython子进程管道无缓冲行为
【发布时间】:2016-07-18 08:51:09
【问题描述】:

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

从子流程导入 Popen, PIPE proc = Popen('..some_shell_command..', shell=True, stdout=PIPE) fd = open("/tmp/procout", "wb") 而真: 数据 = proc.stdout.read(1024) 如果长度(数据)== 0: 休息 fd.write(数据) fd.close()

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

  • 假设子进程应该产生 500GB 的数据,是否所有这些数据都存储在内存中,直到父进程全部读取它们? (或)
  • 子进程是否会等待父进程读取 1024 字节的数据,然后再将下一个 1024 字节写入标准输出? (或)
  • 子进程会在操作系统管道缓冲区填满后等待,一旦父进程读取,子进程会再次恢复写入吗? (或)
  • ??

【问题讨论】:

    标签: python pipe subprocess buffer


    【解决方案1】:

    回答您的问题:

    • 不,它不会存储在内存中。子进程在超过pipe-max-size限制(cat /proc/sys/fs/pipe-max-size)后会卡在write操作上;
    • 子进程会写1M左右才会卡住,直到父进程读到数据块。在此子进程将按照读取的速度依次写入接下来的 1024 个字节;
    • 是的,在阻塞 IO 的情况下,当调用 write 系统调用时,该进程将被操作系统阻塞。在非阻塞 IO 的情况下,我希望 write syscall 将返回 EAGAIN 或其他系统特定的错误。

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

    【讨论】:

      猜你喜欢
      • 2020-08-18
      • 2021-03-30
      • 1970-01-01
      • 2010-11-14
      • 2011-04-05
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      相关资源
      最近更新 更多