Best way to prevent zombie processes

Cameron Simpson cs at zip.com.au
Sun May 31 21:03:01 EDT 2015


On 31May2015 23:33, Cecil Westerhof <Cecil at decebal.nl> wrote:
>At the moment I have the following code:
>    os.chdir(directory)
>    for document in documents:
>        subprocess.Popen(['evince', document])
>
>With this I can open several documents at once. But there is no way to
>know when those documents are going to be closed. This could/will lead
>to zombie processes. (I run it on Linux.) What is the best solution to
>circumvent this?

The standard trick is to make the process a grandchild instead of a child.  
Fork, kick off subprocess, exit (the forked child).

But provided you will collect the children eventually then zombies are only 
untidy, not very resource wasteful. They are essentially just slots in the 
process table left around so that exit status can be collected; the resources 
associated with the full process (memory, open file, etc) have already been 
freed.

>I was thinking about putting all Popen instances in a list. And then
>every five minutes walk through the list and check with poll if the
>process has terminated. If it has it can be released from the list.
>Of-course I need to synchronise those events. Is that a good way to do
>it?

It is reasonable.

Alternatively, and more responsively, you could have a process collection 
Thread. It would loop indefinitely, calling os.wait(). That will block until a 
child process exits (any of them), so it is not a busy loop. When wait() 
returns, look up the pid in your list of dispatched subprocess children and do 
whatever cleanup you intend. (If it is just zombies, the os.wait() cleans that 
part for you.)

One thing you do need to keep in mind with such a task is that it will 
os.wait() _all_ child processes. If there are other children which exit, not 
spawned by your specific calls (earlier children or children made by some 
library function), you must be prepared to receive pids which (a) are not in 
your list of "evince" etc tasks and (b) to be collecting pids which other 
subsystems might have wanted to collect themselves. The latter is uncommon (at 
least, uncommon for such things to occur and you the programmer to be unaware 
of them).

Anyway, that is simple and effective and immediate.

Cheers,
Cameron Simpson <cs at zip.com.au>

If everyone is thinking alike, then someone isn't thinking.     - Patton



More information about the Python-list mailing list