Python不断阅读Popen(Windows)

时间:2016-06-20 09:47:38

标签: python windows io subprocess

我试着stdout.readline并在另一个.py文件中为我们multiprocessing.Queue上的结果(即每行打印到终端)。但是,电话:

res = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1 )
with res.stdout:
    for line in iter(res.stdout.readline, b''):
        print line
res.wait()

将在过程完成后阻止并显示结果(如果未返回退出代码则完全没有)。

我已经浏览了SO以获得答案,并尝试设置bufsize = 1,使用filedescriptors等生成处理读取的线程。似乎无效。我可能不得不使用模块pexpect,但我不确定它是如何工作的。

我也试过

 def enqueue_output(self, out, queue):
    for line in iter(out.readline, b''):
        queue.put([line])
    out.close()

要将数据放入队列,但由于out.readline似乎阻止,结果将是相同的。

简而言之:如何在打印时将子进程输出提供给我?它一次打印1-10行的块,但是当过程完成时它们会返回给我,也会被换行符分隔。

相关:

Python subprocess readlines() hangs

Python: read streaming input from subprocess.communicate()

Non-blocking read on a subprocess.PIPE in python

1 个答案:

答案 0 :(得分:1)

正如@eryksun所解释的那样,并且你的评论已经证实,缓冲的原因是C应用程序使用printf

默认情况下,printf缓冲其输出,但输出在换行符上刷新,或者当输出指向终端时发生读取。当输出定向到文件或管道时,实际输出仅在缓冲区已满时发生。

幸运的是,在Windows上,没有低级缓冲(*)。这意味着在程序开头附近调用setvbuf(stdout, NULL, _IONBF, 0);就足够了。但遗憾的是,您根本不需要缓冲(_IONBF),因为Windows上的行缓冲实现为完全缓冲。

(*)在Unix或Linux系统上,底层系统调用可以添加自己的缓冲。这意味着使用低级别write(1, buf, strlen(buf));的程序将在Windows上无缓冲,但在标准输出连接到管道或文件时仍将在Linux上进行缓冲。