scarus has asked for the wisdom of the Perl Monks concerning the following question:

How can I kill children's of children by parent process? The processes are up too three level hirarcy.
[level 1] [Process A]<br> [level 2] [PA_X] [PA_Y]<br> [level 3] [PA_X1, PA_X2][PA_Y1,PA_Y2,PA_Y3]
If Ctrl + C caught then if I use "killfam" to kill level 2 process which will also kill level 2 child (level 3 processes)?

Replies are listed 'Best First'.
Re: Killing children's of children
by pjotrik (Friar) on Jul 17, 2008 at 09:39 UTC
    You'll have to use some kind of inter-process communication (perlipc)
    • store process ids in shared memory
    • install a signal handler in the child, that will in turn kill its children
    • ...
Re: Killing children's of children
by pc88mxer (Vicar) on Jul 17, 2008 at 12:45 UTC
    On Unix systems you can create groups of processes and send a signal to every process in a group by calling kill() with a negative signal number. Have a look at the documentation for setpgrp() and getpgrp().

    For a quick overview of process groups, have a look at this link: UNIX Signals and Process Groups.

      I'd second what pc88mxer suggested. — Here's a demo snippet illustrating the idea (Linux version):

      #!/usr/bin/perl my $sid = getppid; # for the 'ps' process selection only if (my $pid = fork()) { sleep 1; # wait somewhat until tree of children is set up # show related processes system "ps f -s $sid -o pid,ppid,pgrp,sid,cmd"; # kill process group after timeout sleep 10; kill -9, $pid; wait; print "killed children\n"; # show remaining processes system "ps f -s $sid -o pid,ppid,pgrp,sid,cmd"; # do something else... sleep 10; } elsif (defined $pid) { # create new process group setpgrp; # run something (consisting of several processes) that hangs system 'bash -c "cat; echo"'; exit; } else { die "couldn't fork"; }

      Sample output:

      $ ./698259.pl PID PPID PGRP SID CMD 2963 2960 2963 2963 bash 4074 2963 4074 2963 \_ /usr/bin/perl ./698259.pl 4075 4074 4075 2963 \_ /usr/bin/perl ./698259.pl 4076 4075 4075 2963 | \_ bash -c cat; echo 4077 4076 4075 2963 | \_ cat 4078 4074 4074 2963 \_ ps f -s 2963 -o pid,ppid,pgrp,sid,cmd killed children PID PPID PGRP SID CMD 2963 2960 2963 2963 bash 4074 2963 4074 2963 \_ /usr/bin/perl ./698259.pl 4079 4074 4074 2963 \_ ps f -s 2963 -o pid,ppid,pgrp,sid,cmd

      As you can see in the PGRP column, the three child processes in question all belong to the same process group (here 4075).

      The idea should in principle even be portable to Windows (never tried it myself though...). As BrowserUk recently noted, that would be Win32::CreateProcess with CREATE_NEW_PROCESS_GROUP.

Re: Killing children's of children
by jettero (Monsignor) on Jul 17, 2008 at 10:32 UTC

    You could also, possibly, walk through /proc/$$ or the equivalent (depending on your platform).

    IPC is probably a better plan though.

    -Paul

Re: Killing children's of children
by eyepopslikeamosquito (Archbishop) on Jul 17, 2008 at 12:51 UTC

    You'll get more and better assistance if you take the time to explain in more detail what you are trying to achieve and why. And what plaform you are running on.

    To kill a parent and all its children on Unix, you can make the parent a process group leader via the Perl builtin setpgrp function or the POSIX module. With that done, any children this process creates will also be a member of this process group, so sending a signal to this process group will kill the parent and all its children and their children and so on.

    On Windows, which does not support process groups, you can achieve the same thing via Win32 Jobs, accessible from Perl via the Win32::Job module.

Re: Killing children's of children
by zentara (Cardinal) on Jul 17, 2008 at 14:42 UTC