Date: 4 Sep 2001 11:42:54 -0700
From: mcafee@artemis.transmeta.com (Sean McAfee)
Subject: Re: How can I find the PID's of my children?
Message-Id: <9n37be$m9n$1@artemis.transmeta.com>

In article <9n335p$9hv$1@panix1.panix.com>, Stan Brown <stanb@panix.com> wrote:
>I'm writing a perlTK script, which will spawn at least one child task to do
>some long runing processing.

>However, I'm going to leave the user the option of canceling from an "exit"
>button on the main window. So I need to be able to send a kill() signal to
>my children.

>Short of making these PID's global variables, when they are spwned, how can
>I detrmine what children, my runing perl process is the parent of?

What's wrong with keeping track of the PIDs yourself?

my @children;

sub fork_child {
    defined(my $pid = fork()) or die "Can't fork: $!\n";
    if ($pid == 0) {
        # child stuff
        exit;
    }
    push @children, $pid;
}

sub terminate_program {
    kill TERM => @children;
}

If some of the children could terminate before the end of your main
program, you could get a little fancier:

my %children;

$SIG{CHLD} = sub { my $pid = wait; delete $children{$pid} };

sub fork_child {
    defined(my $pid = fork()) or die "Can't fork: $!\n";
    if ($pid == 0) {
        # child stuff
        exit;
    }
    $children{$pid} = 1;
}

sub terminate_program {
    kill TERM => keys %children;
}

If you're morally opposed to this approach for some reason, you'll have to
use some kind of OS-supplied feature to find your children, like parsing
the output of ps:

open PS, 'ps -ef |' or die "Can't fork: $!\n";
while (<PS>) {
    my @field = split;
    if ($field[2] == $$) {
        kill TERM => $field[1];
    }
}

Of course, the appropriate switches to ps are highly OS-dependent.

-- 
Sean McAfee                                                mcafee@umich.edu
print eval eval eval eval eval eval eval eval eval eval eval eval eval eval
q!q@q#q$q%q^q&q*q-q=q+q|q~q:q? Just Another Perl Hacker ?:~|+=-*&^%$#@!


