How to limit program execution time when using a subprocess?

I want to use a subprocess to run the program, but I need to limit the execution time. For example, if it lasts more than 2 seconds, I want to kill him.

For regular programs, kill () works well. But if I try to run /usr/bin/time something , kill () cannot really kill the program.

But my code below does not look very good, the program is still working.

 import subprocess import time exec_proc = subprocess.Popen("/usr/bin/time -f \"%e\\n%M\" ./son > /dev/null", stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True) max_time = 1 cur_time = 0.0 return_code = 0 while cur_time <= max_time: if exec_proc.poll() != None: return_code = exec_proc.poll() break time.sleep(0.1) cur_time += 0.1 if cur_time > max_time: exec_proc.kill() 
+6
python subprocess kill
source share
3 answers

do it like this on the command line:

 perl -e 'alarm shift @ARGV; exec @ARGV' <timeout> <your_command> 

this will run the <your_command> and end it in <timeout> second.

dummy example:

 # set time out to 5, so that the command will be killed after 5 second command = ['perl', '-e', "'alarm shift @ARGV; exec @ARGV'", "5"] command += ["ping", "www.google.com"] exec_proc = subprocess.Popen(command) 

or you can use signal.alarm () if you want it with python, but this is the same.

+3
source share

If you are using Python 2.6 or later, you can use the multiprocessing module.

 from multiprocessing import Process def f(): # Stuff to run your process here p = Process(target=f) p.start() p.join(timeout) if p.is_alive(): p.terminate() 

In fact, multiprocessing is the wrong module for this task, as it is just a way to control how long the thread has been running. You have no control over the children that the thread can execute. As the singularity suggests, using signal.alarm is the usual approach.

 import signal import subprocess def handle_alarm(signum, frame): # If the alarm is triggered, we're still in the exec_proc.communicate() # call, so use exec_proc.kill() to end the process. frame.f_locals['self'].kill() max_time = ... stdout = stderr = None signal.signal(signal.SIGALRM, handle_alarm) exec_proc = subprocess.Popen(['time', 'ping', '-c', '5', 'google.com'], stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) signal.alarm(max_time) try: (stdout, stderr) = exec_proc.communicate() except IOError: # process was killed due to exceeding the alarm finally: signal.alarm(0) # do stuff with stdout/stderr if they're not None 
+9
source share

I use os.kill (), but not sure if it works on all OSs.
The following is the pseudo code and see the Doug Hellman page .

 proc = subprocess.Popen(['google-chrome']) os.kill(proc.pid, signal.SIGUSR1)</code> 
0
source share

All Articles