3

code in fork_child.py

from subprocess import Popen
child = Popen(["ping", "google.com"], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out, err = child.communicate()

I run it from a terminal window as -

$python fork_child.py

From another terminal window if I get the PID of fork_child.py and kill it with SIGTERM, "ping" doesn't get killed. How do I make sure that ping too gets killed when fork_child receives a SIGTERM ?

arc000
  • 833
  • 1
  • 9
  • 16
  • You install a [`signal`](https://docs.python.org/3.4/library/signal.html "The signal module documentation.") handler for `SIGTERM` that kills the subprocess... – Bakuriu Jan 19 '15 at 13:14
  • can you point me to an example ? – arc000 Jan 19 '15 at 13:17
  • see https://docs.python.org/3.4/library/signal.html#example –  Jan 19 '15 at 13:19
  • related: [Python: how to kill child process(es) when parent dies?](http://stackoverflow.com/q/23434842/4279) – jfs Jan 19 '15 at 21:39

2 Answers2

5

Children don't automatically die when the parent process is killed. They die if:

  • The parent forwards the signal and waits for the children to terminate
  • When the child tries to communicate with the parent, for example via stdio. That only works if the parent also created the file descriptors which the child uses.

The signals module contains examples how to write a signal handler.

So you need to:

  • collect all children in a list
  • install a signal handler
  • in the handler, iterate over all the child processes
  • For each child process, invoke child.terminate() followed by child.wait()

The wait() is necessary to allow the OS to garbage collect the child process. If you forget it, you may end up with zombie processes.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • I didn't get the statement - " That only works if the parent also created the file descriptors which the child uses". Could you please elaborate a bit ? – arc000 Jan 19 '15 at 14:39
  • 1
    If the parent process is killed, all it's resources are closed. If you create a child and connect its stdio descriptors with the one from the parent, the child will still be able to do stdio - to the same console which the parent used. But the parent can also create pipes. If the parent dies, one end of the pipe is closed. The child still holds the other end. At that time, nothing happens. But the next time, the child tries to read/write to such a pipe, it gets an error. – Aaron Digulla Jan 19 '15 at 14:47
0

A simple way to kill the whole process tree in the shell is to kill its process group i.e., instead of kill $pid, run:

$ kill -TERM -$pid

Notice: the pid is negated.

Shell creates a new process group for each command (pipeline) therefore you won't kill innocent bystanders.

If descendant processes do not create their own independent process groups; they all die.

See Best way to kill all child processes.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670