Python: ¿Cómo echar un vistazo a un objeto pty para evitar el locking?

Estoy usando pty para leer sin bloquear la salida estándar de un proceso como este:

 import os import pty import subprocess master, slave = pty.openpty() p = subprocess.Popen(cmd, stdout = slave) stdout = os.fdopen(master) while True: if p.poll() != None: break print stdout.readline() stdout.close() 

Todo funciona bien, excepto que el while-loop vez en cuando se bloquea. Esto se debe al hecho de que la línea de print stdout.readline() está esperando que se lea algo de la print stdout.readline() . Pero si el progtwig ya terminó, mi pequeño script allí colgará para siempre.

Mi pregunta es: ¿hay una manera de mirar dentro del objeto stdout y verificar si hay datos disponibles para leer? Si este no es el caso, debe continuar a través del while-loop donde descubrirá que el proceso ya terminó y rompe el bucle.

Sí, use la encuesta del módulo de selección :

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

y al mismo tiempo usar:

 l = q.poll(0) if not l: pass # no input else: pass # there is some input 

La respuesta de select.poll () es muy clara, pero no funciona en Windows. La siguiente solución es una alternativa. No le permite ver la salida estándar, pero proporciona una alternativa de no locking a readline () y se basa en esta respuesta :

 from subprocess import Popen, PIPE from threading import Thread def process_output(myprocess): #output-consuming thread nextline = None buf = '' while True: #--- extract line using read(1) out = myprocess.stdout.read(1) if out == '' and myprocess.poll() != None: break if out != '': buf += out if out == '\n': nextline = buf buf = '' if not nextline: continue line = nextline nextline = None #--- do whatever you want with line here print 'Line is:', line myprocess.stdout.close() myprocess = Popen('myprogram.exe', stdout=PIPE) #output-producing process p1 = Thread(target=process_output, args=(dcmpid,)) #output-consuming thread p1.daemon = True p1.start() #--- do whatever here and then kill process and thread if needed if 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() 

Otras soluciones para la lectura sin locking se han propuesto aquí , pero no funcionaron para mí:

  1. Las soluciones que requieren readline (incluidas las basadas en cola) siempre se bloquean. Es difícil (¿imposible?) Matar el hilo que ejecuta readline. Solo se mata cuando finaliza el proceso que lo creó, pero no cuando se mata el proceso de producción de salida.
  2. La mezcla de fcntl de bajo nivel con las llamadas de readline de alto nivel puede no funcionar correctamente, como lo ha señalado anonnn.
  3. El uso de select.poll () está limpio, pero no funciona en Windows de acuerdo con los documentos de Python.
  4. El uso de bibliotecas de terceros parece excesivo para esta tarea y agrega dependencias adicionales.