14

This has probably been asked but I cannot find anything regarding a subprocess.call timeout when using python 2.7

1

5 Answers 5

16

A simple way I've always done timeouts with 2.7 is utilizing subprocess.poll() alongside time.sleep() with a delay. Here's a very basic example:

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 e.g. print, check resources, etc. time.sleep(delay) timeout -= delay 

If you set x = 600, then your timeout would amount to 10 minutes. While task.poll() will query whether or not the process has terminated. time.sleep(delay) will sleep for 1 second in this case, and then decrement the timeout by 1 second. You can play around with that part to your heart's content, but the basic concept is the same throughout.

Hope this helps!

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

Sign up to request clarification or add additional context in comments.

3 Comments

This doesn't kill the process. You need to add os.killpg(os.getpgid(task.pid), signal.SIGTERM)
@AaronS I think task.terminate() does virtually the same.
if you don't change the process group of the new task, os.killpg(os.getpgid(task.pid) may kill all the processes with the same pg, not only the process executed by subprocess.Popen() and its children(!)
4

You could install subprocess32 module mentioned by @gps -- the backport of the subprocess module from Python 3.2/3.3 for use on 2.x. It works on Python 2.7 and it includes timeout support from Python 3.3.

subprocess.call() is just Popen().wait() and therefore to interrupt a long running process in timeout seconds:

#!/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() 

If the child process may end sooner then a portable solution is to use Timer() as suggested in @sussudio's answer:

#!/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() 

On Unix, you could use SIGALRM as suggested in @Alex Martelli's answer:

#!/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() 

To avoid using threads and signals here, subprocess module on Python 3 uses a busy loop with waitpid(WNOHANG) calls on Unix and winapi.WaitForSingleObject() on Windows.

Comments

2

You can try to use "easyprocess":

https://github.com/ponty/EasyProcess

It has many features that you need like "timeout".

Comments

0

You can use subprocess32 mentioned by @gps, which is backport of the subprocess standard library module from Python 3.2 - 3.5 for use on Python 2.

Firstly, install the subprocess32 module:

pip install subprocess32 

Here's a code snippet:

>>> import subprocess32 >>> print subprocess32.check_output(["python", "--version"]) Python 2.7.12 >>> subprocess32.check_output(["sleep", "infinity"], timeout=3) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/subprocess32.py", line 340, in check_output raise TimeoutExpired(process.args, timeout, output=output) subprocess32.TimeoutExpired: Command '['sleep', 'infinity']' timed out after 3 seconds 

Notice, default timeout=None, which means never timeout.

Comments

-5

In python 3.3 timeout argument was added.

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

1 Comment

Thanks for your response.I know that we are using python 2.7.6

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.