Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kill or terminate subprocess when timeout?

Tags:

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

like image 637
user504909 Avatar asked Nov 11 '10 19:11

user504909


People also ask

How do you kill a subprocess call?

Since subprocess. call waits for the command to complete, you can't kill it programmatically. Your only recourse is to kill it manually via an OS specific command like kill .

How do you stop subprocess?

The killpg() method send the signal to all the process group to terminate the process. Among all these commands, killpg is the method used to kill all the subprocesses. We can also use for loop to kill all the processes by using the kill() method or terminate() method.

Does subprocess wait for command to finish?

subprocess. run() is synchronous which means that the system will wait till it finishes before moving on to the next command.


1 Answers

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.

like image 50
ralphtheninja Avatar answered Sep 19 '22 03:09

ralphtheninja