Search code examples
pythontimeoutsubprocesskillsignals

Kill or terminate subprocess when timeout?


I would like to repeatedly execute a subprocess as fast as possible. However, sometimes the process will take too long, so I want to kill it. I use signal.signal(...) like below:

ppid=pipeexe.pid
signal.signal(signal.SIGALRM, stop_handler)

signal.alarm(1)
.....
def stop_handler(signal, frame):
    print 'Stop test'+testdir+'for time out'
    if(pipeexe.poll()==None and hasattr(signal, "SIGKILL")):
         os.kill(ppid, signal.SIGKILL)
         return False

but sometime this code will try to stop the next round from executing. Stop test/home/lu/workspace/152/treefit/test2for time out /bin/sh: /home/lu/workspace/153/squib_driver: not found ---this is the next execution; the program wrongly stops it.

Does anyone know how to solve this? I want to stop in time not execute 1 second the time.sleep(n) often wait n seconds. I do not want that I want it can execute less than 1 second


Solution

  • You could do something like this:

    import subprocess as sub
    import threading
    
    class RunCmd(threading.Thread):
        def __init__(self, cmd, timeout):
            threading.Thread.__init__(self)
            self.cmd = cmd
            self.timeout = timeout
    
        def run(self):
            self.p = sub.Popen(self.cmd)
            self.p.wait()
    
        def Run(self):
            self.start()
            self.join(self.timeout)
    
            if self.is_alive():
                self.p.terminate()      #use self.p.kill() if process needs a kill -9
                self.join()
    
    RunCmd(["./someProg", "arg1"], 60).Run()
    

    The idea is that you create a thread that runs the command and to kill it if the timeout exceeds some suitable value, in this case 60 seconds.