Kevin Ding
Kevin Ding

Reputation: 814

python Popen hangs

I use Popen to open tclsh, and try to run puts aaaaaaaaaaa... command(aaa... is very long) by sending command through PIPE

It works fine, but, when I run the command twice (aaaa... need long enough), and I read stdout by PIPE, the code will hang

I tried to enlarge default bufsize, however it doesn't work

what's going on under the hook? anyone can help?

proc = Popen(
    ['C:\\Tcl\\bin\\tclsh.exe'],
    stdin=PIPE,
    stdout=PIPE,
    stderr=PIPE
)

proc.stdin.write(bytearray('puts ' + 'a' * 100000 + 'ends\n', 'utf-8'))
proc.stdin.write(bytearray('puts ' + 'a' * 100000 + 'ends\n', 'utf-8'))
proc.stdin.flush()

stdout = b''
while proc.poll() == None:
    if stdout.endswith(b'ends'):
        break
    else:
        stdout += proc.stdout.read1(1)

print(stdout.decode('utf-8'))

finally, i use tempfile instead PIPE in stdout

    self._tempfile = tempfile.mktemp()
    self._tempfile_in = open(self._tempfile, 'wb')
    self._tempfile_out = open(self._tempfile, 'rb')

    self._process = subprocess.Popen(
        [self.tcl_exe] + list(self.tcl_exe_args),
        stdin = subprocess.PIPE,
        stdout = self._tempfile_in,
        stderr = subprocess.PIPE)

......

    self._tempfile_out.read1(1)

Upvotes: 2

Views: 1167

Answers (1)

Tim Roberts
Tim Roberts

Reputation: 54698

The pipe buffers are not infinitely large. You filled the stdin buffer, then tclsh filled its stdout buffer, and it can't move forward to read the next line until YOU pull something from stdout. So, you're blocked in the second write.

Upvotes: 3

Related Questions