为什么Popen.stdout上的readline阻塞?

时间:2018-01-10 17:44:34

标签: python subprocess buffer

所以我正在研究一个python脚本,它必须与一个可执行文件(就像python解释器一样)有一个交互式shell。我用解决方案找到了类似场景的一些描述,但它们似乎都没有解决我的问题。 我试着编写好的面向对象的代码来完成这个技巧。但是当我尝试从子进程的stdout读取时,解释器永远陷入困境,我不明白为什么。这是我的代码:

这是main.py:

import subprocess_wrapper as sw

print("Will start now.")

python = "python3"

proc = sw.SubprocessWrapper(python)
print("Output: ", proc.get_next_output())
print("------------")

这是subprocess_wrapper.py

import subprocess as sb
import os
from time import sleep

class SubprocessWrapper(sb.Popen):

    def __init__(self, p_executable_filename):
        self.executable_filename = p_executable_filename
        super(SubprocessWrapper, self).__init__(self.executable_filename, stdin=sb.PIPE, stdout=sb.PIPE, shell=True)

    def get_next_output(self):
        next_output = ""
        input_lines = 0

        while input_lines < 1:
            new_line = self.stdout.readline().decode()
            next_output += new_line
            if new_line.startswith('>'):
                input_lines += 1

            self.stdout.flush()

        return next_output

    def write(self, p_input):
        print("Passing {} to subprocess.".format(p_input))
        self.stdin.write('{}\n'.format(p_input).encode())
        self.stdin.flush()
        print("Done passing.")

我尝试用此做法: 当python解释器等待用户输入时,它通过打印&#34;&gt;&gt;&gt;&#34;来指示这一点。因此,get_next_output方法应返回stdout缓冲区中的所有内容,直到它读取&#34;&gt;&#34;在一些行的开头。

会发生什么: 程序在到达readline()行时就会卡住。据我所知,readline()会阻塞,直到将某些内容写入缓冲区。这很好,因为我不想在缓冲空闲时读取缓冲时间。我找到的一些解决方案使用fcntl来更改缓冲区的阻塞标志。但在我的情况下这不应该是必要的,因为我实际上想要等待写入其中的东西。

我的问题: 1.为什么readline()确实会永远阻塞,即使应该在其中写入内容。 2.如何在不损失阻塞缓冲区的性能优势的情况下修改我的代码以按预期工作(以避免主动等待)。

0 个答案:

没有答案