为什么 `readline` return 不用于 `subprocess.stdout`?
Why doesn't `readline` return for `subprocess.stdout`?
我使用 Python subprocess
分叉一个 C 应用程序并打开一个管道到 stdout
。
app = subprocess.Popen(args, stdout=subprocess.PIPE)
应用程序向 stdout
写入几行,如下所示:
printf("Line 0\n");
printf("Line 1\n");
printf("Line 2\n");
我尝试在应用程序退出前阅读我的 Python 脚本中的这些行:
line = app.stdout.readline()
但是,readline
会无限期地阻止 return 任何内容,即使我希望阅读 Line 0
、Line 1
和 Line 2
,对 readline
的三个单独调用。我注意到当应用程序最终退出时,readline
return 是预期的内容。但是,我希望 readline
到 return 预期的内容一旦传递给 printf
。发生了什么事?
根据 this Whosebug question,printf
只有当输出设备是交互式的(例如,终端)时,才会在换行符上刷新其输出。 当输出设备是非交互式的(例如,Python 子进程管道、文件等)时,stdout
是完全缓冲的,因此只有在缓冲区已满,当手动调用 fflush(stdout)
时,或者当缓冲区被强制刷新时(例如,在进程退出时)。
因此,readline
没有 return 因为应用程序的 stdout
从未被刷新,所以 readline
没有任何内容可读。将应用程序代码更改为此可以解决问题:
printf("Line 0\n");
printf("Line 1\n");
printf("Line 2\n");
fflush(stdout); // New line
其他人可能希望用setvbuf
设置stdout
的缓冲模式而不是调用fflush
.
我对此感到惊讶,因为对 printf
的普遍理解是它会刷新换行符,但并非在所有情况下都会发生这种情况。
我使用 Python subprocess
分叉一个 C 应用程序并打开一个管道到 stdout
。
app = subprocess.Popen(args, stdout=subprocess.PIPE)
应用程序向 stdout
写入几行,如下所示:
printf("Line 0\n");
printf("Line 1\n");
printf("Line 2\n");
我尝试在应用程序退出前阅读我的 Python 脚本中的这些行:
line = app.stdout.readline()
但是,readline
会无限期地阻止 return 任何内容,即使我希望阅读 Line 0
、Line 1
和 Line 2
,对 readline
的三个单独调用。我注意到当应用程序最终退出时,readline
return 是预期的内容。但是,我希望 readline
到 return 预期的内容一旦传递给 printf
。发生了什么事?
根据 this Whosebug question,printf
只有当输出设备是交互式的(例如,终端)时,才会在换行符上刷新其输出。 当输出设备是非交互式的(例如,Python 子进程管道、文件等)时,stdout
是完全缓冲的,因此只有在缓冲区已满,当手动调用 fflush(stdout)
时,或者当缓冲区被强制刷新时(例如,在进程退出时)。
因此,readline
没有 return 因为应用程序的 stdout
从未被刷新,所以 readline
没有任何内容可读。将应用程序代码更改为此可以解决问题:
printf("Line 0\n");
printf("Line 1\n");
printf("Line 2\n");
fflush(stdout); // New line
其他人可能希望用setvbuf
设置stdout
的缓冲模式而不是调用fflush
.
我对此感到惊讶,因为对 printf
的普遍理解是它会刷新换行符,但并非在所有情况下都会发生这种情况。