When I kick off a python script from within another python script using the subprocess module, a zombie process is created when the subprocess "completes". I am unable to kill this subprocess unless I kill my parent python process.
Is there a way to kill the subprocess without killing the parent? I know I can do this by using wait(), but I need to run my script with no_wait().
If you delete the subprocess object, using del to force garbage collection, that will cause the subprocess object to be deleted and then the defunct processes will go away without terminating your interpreter. You can try this out in the python command line interface first.
I'm not entirely sure what you mean by
no_wait()
. Do you mean you can't block waiting for child processes to finish? Assuming so, I think this will do what you want:A zombie process is not a real process; it's just a remaining entry in the process table until the parent process requests the child's return code. The actual process has ended and requires no other resources but said process table entry.
We probably need more information about the processes you run in order to actually help more.
However, in the case that your Python program knows when the child processes have ended (e.g. by reaching the end of the child stdout data), then you can safely call
process.wait()
:Example output:
Otherwise, you can keep all the children in a list, and now and then
.poll
for their return codes. After every iteration, remember to remove from the list the children with return codes different thanNone
(i.e. the finished ones).Not using
Popen.communicate()
orcall()
will result in a zombie process.If you don't need the output of the command, you can use
subprocess.call()
:If the output is important, you should use
Popen()
andcommunicate()
to get the stdout and stderr.I'm not sure what you mean "I need to run my script with no_wait()", but I think this example does what you need. Processes will not be zombies for very long. The parent process will only
wait()
on them when they are actually already terminated and thus they will quickly unzombify.The output towards the end looks like this:
If you simply use
subprocess.Popen
, you'll be fine - here's how:You can use
.poll()
on the object returned by Popen to check whether it finished (without waiting). If it returnsNone
, the child is still running.Make sure you don't keep references to the Popen objects - if you do, they will not be garbage collected, so you end up with zombies. Here's an example:
In the above example, if you want to get rid of the zombies, you can either
.wait()
on each of the children or.poll()
until the result is notNone
.Either way is fine - either not keeping references, or using
.wait()
or.poll()
.