【问题标题】:Python - How to read from long-running subprocess?Python - 如何从长时间运行的子进程中读取?
【发布时间】:2020-09-26 20:37:38
【问题描述】:

从长时间运行的子进程中读取似乎是可能的,但如果子进程是python3 -i,我只能让它工作:

>>> sub = subprocess.Popen(['python3', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> sub.stdin.write(b'2+3\n')
4
>>> sub.stdin.flush()
>>> sub.stdout.readline()
b'5\n'

用一个小的 echo 程序尝试同样的事情是行不通的:

>>> sub = subprocess.Popen(['./echo'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> sub.stdin.write(b'2+3\n')
4
>>> sub.stdin.flush()
>>> sub.stdout.readline()
^ Hangs here until interrupted with Ctrl-C

echo 从 STDIO 读取并在收到换行符时回显。直接运行时效果很好。这是它的代码:

#include <iostream>
#include <unistd.h>

int main() {
  char message[64];
  uint8_t cursor = 0;
  
  while(true) {
    read(STDIN_FILENO, message + cursor, 1);
    
    if(message[cursor++] == '\n') {
      message[cursor] = 0;
      printf(message);
      cursor = 0;
    }
  }
}

我尝试了一些其他技术,例如.communicate(),结果相似。奇怪的是,subprocess.Popen(['python3'], ...) 在运行 python3 -i 时同样的调用会失败,尽管 python3python3 -i 在终端运行时似乎做同样的事情。

【问题讨论】:

    标签: python python-3.x subprocess


    【解决方案1】:

    问题原来是在子进程的标准输出中缓冲。我通过使用setvbuf (stdout, NULL, _IOLBF, 1024); 设置行缓冲来解决它。如果根本不需要缓冲,可以使用setvbuf (stdout, NULL, _IONBF, 0);

    【讨论】:

      猜你喜欢
      • 2016-08-20
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 2018-05-20
      • 1970-01-01
      相关资源
      最近更新 更多