How to kill all child processes except itself?

Discussion in 'Perl Misc' started by zeal, Dec 5, 2004.

  1. zeal

    zeal Guest

    I have a perl script, part of it as below:
    -------------------------------------------
    $rc = eval{
    my ($rc);
    local $SIG{ALRM} = sub { die "Timeout" };
    alarm $timeout;
    $rc = 0xffff & system $cmd;
    alarm 0;
    return $rc;
    };
    if ( $@ && $@ =~ /Timeout/ ) {
    local $SIG{INT} = 'IGNORE';
    kill INT => -$$;
    $rc = 0x9999;
    }
    --------------------------------------------

    What I want to do is that kill all child processes after the timeout
    but keep the script itself alive. Actually I need to kill all processes
    (the whole process group) invoked from the system() call. The reason I
    need to use system is, I need to analysis the return value "$rc".
    In most cases, the system() can finish before the timeout, however, in
    some cases, it will time out, then I want to kill all the processes
    after the timeout.

    The way I used to do the kill is
    -----------------------------
    local $SIG{INT} = 'IGNORE';
    kill INT => -$$;
    -----------------------------
    I got this from somewhere, it's said that when a SIG sent to a negative
    pid, it will be sent to the whole process group. Since I "INGORE"
    myself, then this shouls satisfy my requirement.

    I run this script in LINUX system.
    Most of the case, it works fine. However, sometimes, I found that when
    the script is finished, some child processes are still running, which
    means that they were not killed.

    And use "pstree -p", I found that those alive child processes's parent
    PID is changed, not the pid of the perl script process.

    My question is how can I completely kill all the child processess?

    BTW: the "$cmd" is used to call "make -f somemakefile", several
    generation of child processes may invoked during the system().

    One example,
    when I run my script.

    31166 2416 0 04:01 pts/0 00:00:00 /usr/bin/perl -w ./regtests.pl


    After it's done, some timeout processes are already killed, but two of
    them are still alive

    pstree -p
    +-sh(31844)---make(31845)---sim(31851)
    +-sh(31856)---make(31857)---sim(31863)

    The parent id is already changed ...

    On one of my debian platform (kernel 2.6), this always happens, most of
    child processes are alive. On other linux platform (including debian
    (kernel 2.4), redhat, gentoo), only some of them can not be killed.
    Any solutions???

    Thanks very much!
    zeal, Dec 5, 2004
    #1
    1. Advertising

  2. zeal wrote:


    > What I want to do is that kill all child processes after the timeout
    > but keep the script itself alive. Actually I need to kill all processes
    > (the whole process group) invoked from the system() call. The reason I
    > need to use system is, I need to analysis the return value "$rc".
    > In most cases, the system() can finish before the timeout, however, in
    > some cases, it will time out, then I want to kill all the processes
    > after the timeout.
    >
    > The way I used to do the kill is
    > -----------------------------
    > local $SIG{INT} = 'IGNORE';
    > kill INT => -$$;
    > -----------------------------
    > I got this from somewhere, it's said that when a SIG sent to a negative
    > pid, it will be sent to the whole process group. Since I "INGORE"
    > myself, then this shouls satisfy my requirement.
    >
    > I run this script in LINUX system.
    > Most of the case, it works fine. However, sometimes, I found that when
    > the script is finished, some child processes are still running, which
    > means that they were not killed.
    >
    > And use "pstree -p", I found that those alive child processes's parent
    > PID is changed, not the pid of the perl script process.


    Is it 1 ? When a process dies it's children are adopted by process 1.

    Note that a process group is not the same thing as all the decentants of
    a process, it is all the processes with the same process group id. When
    a process forks its new child will inherit the parent's PGID. But any
    process can at any time decide to break away form its parent's process
    group and start its own (with a PGID equal to its PID).

    I suggest you look at the PGID of the children that won't die to see if
    they have broken away from the group.

    A neat trick that may help in this cases is to create the tree of
    subrocesses with STDERR/STDOUT redirected to a pipe or pipes then they
    all get killed with a SIGPIPE simply by closing these pipes. This of
    course only works if they don't redirect STDERR and STDOUT.

    This is all more to do with Unix/Linux than it is to do with Perl.
    Brian McCauley, Dec 5, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeff Rodriguez
    Replies:
    23
    Views:
    1,081
    David Schwartz
    Dec 9, 2003
  2. Bob Swerdlow

    Proper way to kill child processes

    Bob Swerdlow, Jun 15, 2004, in forum: Python
    Replies:
    6
    Views:
    1,457
  3. John Salerno
    Replies:
    20
    Views:
    820
    John Salerno
    Aug 11, 2006
  4. Fabio Z Tessitore

    who is simpler? try/except/else or try/except

    Fabio Z Tessitore, Aug 12, 2007, in forum: Python
    Replies:
    5
    Views:
    361
  5. Eric Milford
    Replies:
    3
    Views:
    122
    Peter Booth
    Mar 31, 2009
Loading...

Share This Page