¿Cómo hacer un subprocess.call timeout usando python 2.7.6?

Probablemente se haya pedido esto, pero no puedo encontrar nada con respecto a un subproceso. Tiempo de espera de llamada cuando se utiliza python 2.7

Una forma sencilla de hacer siempre los tiempos de espera con 2.7 es utilizar subprocess.poll() junto con time.sleep() con un retraso. Aquí hay un ejemplo muy básico:

 import subprocess import time x = #some amount of seconds delay = 1.0 timeout = int(x / delay) args = #a string or array of arguments task = subprocess.Popen(args) #while the process is still executing and we haven't timed-out yet while task.poll() is None and timeout > 0: #do other things too if necessary eg print, check resources, etc. time.sleep(delay) timeout -= delay 

Si establece x = 600 , entonces su tiempo de espera sería de 10 minutos. Mientras que task.poll() consultará si el proceso ha terminado o no. time.sleep(delay) dormirá durante 1 segundo en este caso, y luego disminuirá el tiempo de espera en 1 segundo. Puedes jugar con esa parte al contenido de tu corazón, pero el concepto básico es el mismo en todo momento.

¡Espero que esto ayude!

subprocess.poll() https://docs.python.org/2/library/subprocess.html#popen-objects

Puede instalar el módulo subprocess32 mencionado por @gps , el puerto de soporte del módulo de subprocess de Python 3.2 / 3.3 para su uso en 2.x. Funciona en Python 2.7 e incluye soporte de tiempo de espera de Python 3.3.

subprocess.call() es simplemente Popen().wait() y, por lo tanto, interrumpir un proceso de ejecución prolongada en segundos de timeout de timeout :

 #!/usr/bin/env python import time from subprocess import Popen p = Popen(*call_args) time.sleep(timeout) try: p.kill() except OSError: pass # ignore p.wait() 

Si el proceso hijo puede terminar antes, una solución portátil es usar Timer() como se sugiere en la respuesta de @susudio :

 #!/usr/bin/env python from subprocess import Popen from threading import Timer def kill(p): try: p.kill() except OSError: pass # ignore p = Popen(*call_args) t = Timer(timeout, kill, [p]) t.start() p.wait() t.cancel() 

En Unix, puede usar SIGALRM como se sugiere en la respuesta de @Alex Martelli :

 #!/usr/bin/env python import signal from subprocess import Popen class Alarm(Exception): pass def alarm_handler(signum, frame): raise Alarm signal.signal(signal.SIGALRM, alarm_handler) p = Popen(*call_args) signal.alarm(timeout) # raise Alarm in 5 minutes try: p.wait() signal.alarm(0) # reset the alarm except Alarm: p.kill() p.wait() 

Para evitar el uso de subprocesos y señales aquí, el módulo de subprocess en Python 3 utiliza un bucle ocupado con waitpid(WNOHANG) a waitpid(WNOHANG) en Unix y winapi.WaitForSingleObject() en Windows .

Puedes intentar usar “easyprocess” :

https://github.com/ponty/EasyProcess

Tiene muchas características que necesitas como “timeout” .

En Python 3.3 se agregó el argumento de timeout .

https://docs.python.org/3/library/subprocess.html#subprocess.call