views:

228

answers:

3

On Windows, subprocess.Popen.terminate calls win32's TerminalProcess. However, the behavior I see is that child processes of the process I am trying to terminate is still running. Why is that? How do I ensure killing every god damn processes started by the process?

+3  A: 

This is a hard thing to do. Windows does not actually store a process tree in the process space. Nor is it possible to terminate a process and specify that it's children should also die.

One way around that is to use taskkill and tell it to wack the whole tree.

Another way to do it (assuming that you are spawning the top-level process) is to use a module that was developed with this sort of thing in mind: http://benjamin.smedbergs.us/blog/tag/killableprocess/

In order to do this generically for yourself, you have to spend some time building the list backwards. That is, a process stores pointers to it's PARENT, but parents appear to not store information about children.

So you have to look at all the processes in the system (which really isn't that hard), and then manually connect the dots yourself by looking at the parent process field. Then, you select the tree you are interested in and walk the whole thing, killing each node in turn, one by one.

Note that Windows doesn't update a child's parent pointer when the parent dies, so there may be gaps in your tree. I'm not aware of anything you can do about those.

Christopher
+1  A: 

Here are 2 options

  1. Use this exe as a subprocess which kills process trees for you: http://www.latenighthacking.com/projects/2002/kill/

  2. Convert the following C code into Python with ctypes: http://stackoverflow.com/questions/1173342/terminate-a-process-tree-c-for-windows

Unknown
+1  A: 

Put the children in a NT Job object, then you can kill all children

Anders
Job objects seems like the right way to approach this problem; too bad that this isn't integrated with the subprocess module.
Sridhar Ratnakumar