I realize this might be a duplicate of Using module 'subprocess' with timeout. If it is, I apologize, just wanted to clarify something.
I’m creating a subprocess, which I want to run for a certain amount of time, and if it doesn’t complete within that time, I want it to throw an error. Would something along the lines of the following code work or do we have to use a signal like answered in the other question? Thanks in advance!:
def run(self):
self.runTestCmd()
self.waitTestComplete(self.timeout)
def runTestCmd(self):
self.proc = subprocess.Popen("./configure", shell=True)
def waitTestComplete(self, timeout):
st = time.time()
while (time.time()-st) < timeout:
if self.proc.poll() == 0:
return True
else:
time.sleep(2)
raise TestError("timed out waiting for test to complete")
It would, but it has a problem. The process will continue on doing whatever it is you asked it to do even after you’ve given up on it. You’ll have to send the process a signal to kill it once you’ve given up on it if you really want it to stop.
Since you are spawning a new process (
./configurewhich is presumably a configure script) that in turn creates a whole ton of sub-processes this is going to get a little more complex.Then
os.kill(-process.pid, signal.SIGKILL)should kill all the sub-processes. Basically what you are doing is using thepreexec_fnto cause your new subprocess to acquire it’s own session group. Then you are sending a signal to all processes in that session group.Many processes that spawn subprocesses know that they need to clean up their subprocesses before they die. So it behooves you to try being nice to them if you can. Try
os.signal(-process.pid, signal.SIGTERM)first, wait a second or two for the process to exit, then trySIGKILL. Something like this:As a side note, never, ever use
shell=Trueunless you know for absolute certain that’s what you want. Seriously.shell=Trueis downright dangerous and the source of many security issues and mysterious behavior.