Skip to content Skip to sidebar Skip to footer

Python: How To Peek Into A Pty Object To Avoid Blocking?

I am using pty to read non blocking the stdout of a process like this: import os import pty import subprocess master, slave = pty.openpty() p = subprocess.Popen(cmd, stdout = sla

Solution 1:

Yes, use the select module's poll:

importselect
q = select.poll()
q.register(stdout,select.POLLIN)

and in the while use:

l = q.poll(0)
ifnot l:
    pass# no inputelse:
    pass# there is some input

Solution 2:

The select.poll() answer is very neat, but doesn't work on Windows. The following solution is an alternative. It doesn't allow you to peek stdout, but provides a non-blocking alternative to readline() and is based on this answer:

from subprocess import Popen, PIPE
from threading import Thread
defprocess_output(myprocess): #output-consuming thread
    nextline = None
    buf = ''whileTrue:
        #--- extract line using read(1)
        out = myprocess.stdout.read(1)
        if out == ''and myprocess.poll() != None: breakif out != '':
            buf += out
            if out == '\n':
                nextline = buf
                buf = ''ifnot nextline: continue
        line = nextline
        nextline = None#--- do whatever you want with line hereprint'Line is:', line
    myprocess.stdout.close()

myprocess = Popen('myprogram.exe', stdout=PIPE) #output-producing process
p1 = Thread(target=process_output, args=(myprocess,)) #output-consuming thread
p1.daemon = True
p1.start()

#--- do whatever here and then kill process and thread if neededif myprocess.poll() == None: #kill process; will automatically stop thread
    myprocess.kill()
    myprocess.wait()
if p1 and p1.is_alive(): #wait for thread to finish
    p1.join()

Other solutions for non-blocking read have been proposed here, but did not work for me:

  1. Solutions that require readline (including the Queue based ones) always block. It is difficult (impossible?) to kill the thread that executes readline. It only gets killed when the process that created it finishes, but not when the output-producing process is killed.
  2. Mixing low-level fcntl with high-level readline calls may not work properly as anonnn has pointed out.
  3. Using select.poll() is neat, but doesn't work on Windows according to python docs.
  4. Using third-party libraries seems overkill for this task and adds additional dependencies.

Post a Comment for "Python: How To Peek Into A Pty Object To Avoid Blocking?"