Killing all child processes upon parent exit

Discussion in 'Perl Misc' started by bsder, Nov 30, 2005.

  1. bsder

    bsder Guest

    Hi,

    Could anyone please tell me how to kill all child processes when parent
    exit?

    Here is the server code:

    #!/usr/bin/perl

    use strict;
    use Socket;
    use Data::Dumper;

    # forward declaration
    sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }

    $SIG{INT} = $SIG{TERM} =$SIG{HUP} = \&signal_handler;
    $SIG{CHLD} = 'IGNORE';
    $SIG{CLD} = 'IGNORE';

    my %kids = {};
    my $proto = getprotobyname('tcp');
    socket(SOCK,PF_INET,SOCK_STREAM,$proto) || die "socket : $!";
    my $port = 7888;
    my $address = pack_sockaddr_in($port, INADDR_ANY);

    bind(SOCK, $address) || die "bind : $!";

    while (1) {
    listen(SOCK, SOMAXCONN) || die "listen: $!";
    my $hostName = inet_ntoa(INADDR_ANY);
    logmsg "server started on port $port, $hostName";

    sub REAPER {
    my $waitedpid = wait;
    $SIG{CHLD} = \&REAPER;
    logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
    }
    $SIG{CHLD} = \&REAPER;

    print STDOUT "Server host: $hostName\n";
    print STDOUT "Server port: $port\n";
    (my $addr = accept(NEWSOCK,SOCK)) or ($! eq 'Interrupted system
    all' and redo) or die $!;
    select(NEWSOCK); $| = 1; select(STDOUT);

    my $kidpid;
    if (!defined($kidpid = fork())) {
    die "cannot fork: $!";
    }
    elsif ($kidpid == 0) { # child
    my ($cPort, $cHost) = unpack_sockaddr_in($addr);
    my $cHostName = inet_ntoa($cHost);
    print STDOUT "Client host: $cHostName\n";
    print STDOUT "Client port: $cPort\n";
    print NEWSOCK "Welcome to Code Generator.\r\n";

    while (my $m=<NEWSOCK>) {
    $m =~ s/\n|\r//g;
    last if ($m eq ".");
    print NEWSOCK "Server received $m\r\n";
    }
    close(NEWSOCK) || die "close in child: $!";
    delete %kids->{$kidpid};
    exit;
    }
    }


    sub signal_handler
    {
    local $SIG{HUP} = 'IGNORE';
    kill HUP => -$$;
    print STDOUT "going to die\n";
    exit;
    }

    Client code:
    #!/usr/bin/perl


    $domain = 2; # Internet domain
    $type = 1; # Sequenced, reliable, two-way connection, byte streams
    $proto = 6; # Transmission Control Protocol (TCP)
    socket(SOCK,$domain,$type,$proto);
    $host = pack('C4', 127,0,0,1); # localhost = 127.0.0.1
    $port = 1024;
    $address = pack('S n a4 x8', $domain, $port, $host);
    bind(SOCK, $address);
    print STDOUT "Client host: ",join('.',unpack('C4', $host)),"\n";
    print STDOUT "Client port: $port\n";
    $sHost = pack('C4', 127,0,0,1); # localhost = 127.0.0.1
    $sPort = 7888;
    $sAddress = pack('S n a4 x8', $domain, $sPort, $sHost);
    connect(SOCK, $sAddress);
    print STDOUT "Server host: ",join('.',unpack('C4', $sHost)),"\n";
    print STDOUT "Server port: $sPort\n";
    select(SOCK); $| = 1; select(STDOUT);
    while ($m=<SOCK>) {
    print STDOUT $m;
    $m = <STDIN>;
    print SOCK $m;
    }
    close(SOCK);
    exit;

    Thanks
    Sam
     
    bsder, Nov 30, 2005
    #1
    1. Advertising

  2. bsder

    Anno Siegel Guest

    bsder <> wrote in comp.lang.perl.misc:
    > Hi,
    >
    > Could anyone please tell me how to kill all child processes when parent
    > exit?


    What's the problem? You have the PID, Perl has the kill() function.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Nov 30, 2005
    #2
    1. Advertising

  3. bsder

    bsder Guest

    Anno Siegel wrote:
    > bsder <> wrote in comp.lang.perl.misc:
    >
    >>Hi,
    >>
    >>Could anyone please tell me how to kill all child processes when parent
    >>exit?

    >
    >
    > What's the problem? You have the PID, Perl has the kill() function.
    >
    > Anno


    Yes I have added the kill() function in the signal_handler(), is this a
    proper way to add kill() function in signal handler?

    Thanks
    Sam
     
    bsder, Nov 30, 2005
    #3
  4. bsder

    Anno Siegel Guest

    bsder <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > bsder <> wrote in comp.lang.perl.misc:
    > >
    > >>Hi,
    > >>
    > >>Could anyone please tell me how to kill all child processes when parent
    > >>exit?

    > >
    > >
    > > What's the problem? You have the PID, Perl has the kill() function.
    > >
    > > Anno

    >
    > Yes I have added the kill() function in the signal_handler(), is this a
    > proper way to add kill() function in signal handler?


    In which signal handler? That doesn't make sense. A signal handler is
    activated when the process receives a signal. You want to *send* a
    signal when the process exits, so call kill() when it exits.

    If you want to automate the kill-on-exit, you could call the kill function
    in an END block. Look up END in perlmod to see the possibilities and
    limitations.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Nov 30, 2005
    #4
  5. bsder

    bsder Guest

    Anno Siegel wrote:
    > bsder <> wrote in comp.lang.perl.misc:
    >
    >>Anno Siegel wrote:
    >>
    >>>bsder <> wrote in comp.lang.perl.misc:
    >>>
    >>>
    >>>>Hi,
    >>>>
    >>>>Could anyone please tell me how to kill all child processes when parent
    >>>>exit?
    >>>
    >>>
    >>>What's the problem? You have the PID, Perl has the kill() function.
    >>>
    >>>Anno

    >>
    >>Yes I have added the kill() function in the signal_handler(), is this a
    >>proper way to add kill() function in signal handler?

    >
    >
    > In which signal handler? That doesn't make sense. A signal handler is
    > activated when the process receives a signal. You want to *send* a
    > signal when the process exits, so call kill() when it exits.
    >

    have you look thru my server code? the signal handler is at the end of
    the server code. I want to kill all its child processes when the server
    code received an interrupt signal.

    sam
    > If you want to automate the kill-on-exit, you could call the kill function
    > in an END block. Look up END in perlmod to see the possibilities and
    > limitations.
    >
    > Anno
     
    bsder, Nov 30, 2005
    #5
  6. bsder

    Anno Siegel Guest

    bsder <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > bsder <> wrote in comp.lang.perl.misc:
    > >
    > >>Anno Siegel wrote:
    > >>
    > >>>bsder <> wrote in comp.lang.perl.misc:
    > >>>
    > >>>
    > >>>>Hi,
    > >>>>
    > >>>>Could anyone please tell me how to kill all child processes when parent
    > >>>>exit?
    > >>>
    > >>>
    > >>>What's the problem? You have the PID, Perl has the kill() function.
    > >>>
    > >>>Anno
    > >>
    > >>Yes I have added the kill() function in the signal_handler(), is this a
    > >>proper way to add kill() function in signal handler?

    > >
    > >
    > > In which signal handler? That doesn't make sense. A signal handler is
    > > activated when the process receives a signal. You want to *send* a
    > > signal when the process exits, so call kill() when it exits.
    > >

    > have you look thru my server code?


    No. You gave us 95 lines of code with no indication how it relates
    to your question. I haven't read it.

    > the signal handler is at the end of
    > the server code. I want to kill all its child processes when the server
    > code received an interrupt signal.


    That would kill the children only if the process itself is killed by
    that specific signal. You can do that, but I'd still suggest taking
    care of the children in an END block. You must still catch the signals
    you expect to receive because an uncaught exception bypasses END. It
    suffices to catch them unspecifically with "sub { die }".

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Nov 30, 2005
    #6
  7. bsder

    bsder Guest

    Anno Siegel wrote:
    > bsder <> wrote in comp.lang.perl.misc:
    >
    >>Anno Siegel wrote:
    >>
    >>>bsder <> wrote in comp.lang.perl.misc:
    >>>
    >>>
    >>>>Anno Siegel wrote:
    >>>>
    >>>>
    >>>>>bsder <> wrote in comp.lang.perl.misc:
    >>>>>
    >>>>>
    >>>>>
    >>>>>>Hi,
    >>>>>>
    >>>>>>Could anyone please tell me how to kill all child processes when parent
    >>>>>>exit?
    >>>>>
    >>>>>
    >>>>>What's the problem? You have the PID, Perl has the kill() function.
    >>>>>
    >>>>>Anno
    >>>>
    >>>>Yes I have added the kill() function in the signal_handler(), is this a
    >>>>proper way to add kill() function in signal handler?
    >>>
    >>>
    >>>In which signal handler? That doesn't make sense. A signal handler is
    >>>activated when the process receives a signal. You want to *send* a
    >>>signal when the process exits, so call kill() when it exits.
    >>>

    >>
    >>have you look thru my server code?

    >
    >
    > No. You gave us 95 lines of code with no indication how it relates
    > to your question. I haven't read it.
    >
    >
    >>the signal handler is at the end of
    >>the server code. I want to kill all its child processes when the server
    >>code received an interrupt signal.

    >
    >
    > That would kill the children only if the process itself is killed by
    > that specific signal. You can do that, but I'd still suggest taking
    > care of the children in an END block. You must still catch the signals
    > you expect to receive because an uncaught exception bypasses END. It
    > suffices to catch them unspecifically with "sub { die }".
    >
    > Anno


    I just want to follow C traditional style. There is no END style in C
    anyway. well.. may be good just put kill() in the END block..

    Thanks
    Sam
     
    bsder, Nov 30, 2005
    #7
  8. bsder

    Anno Siegel Guest

    bsder <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > bsder <> wrote in comp.lang.perl.misc:
    > >>Anno Siegel wrote:
    > >>>bsder <> wrote in comp.lang.perl.misc:
    > >>>>Anno Siegel wrote:
    > >>>>>bsder <> wrote in comp.lang.perl.misc:


    [...]

    > >>>>>>Could anyone please tell me how to kill all child processes when parent
    > >>>>>>exit?


    [...]

    > >>the signal handler is at the end of
    > >>the server code. I want to kill all its child processes when the server
    > >>code received an interrupt signal.

    > >
    > >
    > > That would kill the children only if the process itself is killed by
    > > that specific signal. You can do that, but I'd still suggest taking
    > > care of the children in an END block. You must still catch the signals
    > > you expect to receive because an uncaught exception bypasses END. It
    > > suffices to catch them unspecifically with "sub { die }".
    > >
    > > Anno

    >
    > I just want to follow C traditional style. There is no END style in C
    > anyway. well.. may be good just put kill() in the END block..


    I took a look back at your code now you've said what part of it you
    have problems with. One possible problem is that you set the signal
    handler before you fork, so the kids have a (HUP-) handler too. It
    looks to me that the kids should eventually die anyway, but it is
    probably not what you want. Try setting the handler in the parent
    only (after fork), or reset it in the kids.

    For a Perl solution I'd still prefer END {}, but if you need a prototype
    for a C(++) program, by all means debug the sig-handler solution. Is the
    handler actually invoked? Does it succeed in sending the signal? What
    is the return value of kill? Do the kids receive the signal? What
    happens if you give an explicit list of pids instead of signalling the
    process group?

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Nov 30, 2005
    #8
  9. bsder wrote:

    > Could anyone please tell me how to kill all child processes when parent
    > exit?


    A neat trick on Unix is to open a FIFO before you fork and have the
    child processes close the reading end (keeping open the writing end).

    When the parent exists all the children get a SIGPIPE.

    This, of course, has nothing to do with Perl - you can use this trick
    in any language.
     
    Brian McCauley, Nov 30, 2005
    #9
  10. bsder

    Guest

    bsder <> wrote:
    > Hi,
    >
    > Could anyone please tell me how to kill all child processes when parent
    > exit?



    > elsif ($kidpid == 0) { # child
    > my ($cPort, $cHost) = unpack_sockaddr_in($addr);
    > my $cHostName = inet_ntoa($cHost);
    > print STDOUT "Client host: $cHostName\n";
    > print STDOUT "Client port: $cPort\n";
    > print NEWSOCK "Welcome to Code Generator.\r\n";
    >
    > while (my $m=<NEWSOCK>) {
    > $m =~ s/\n|\r//g;
    > last if ($m eq ".");
    > print NEWSOCK "Server received $m\r\n";
    > }
    > close(NEWSOCK) || die "close in child: $!";
    > delete %kids->{$kidpid};
    > exit;


    What is the point of the delete? For one thing, you've never put
    anything into %kids, neither in parent nor child, so there is nothing to
    delete. For another thing, you are immediately exiting, which mean %kids
    is going away. Why change a variable which is going to disappear a
    nanosecond later anyway? You probably want the delete to be in the
    SIG{CHLD} handler, so that it occurs in the parent process rather than the
    doomed child.

    ....

    > kill HUP => -$$;


    In perl, you want to negate the signal, not the pid. But better yet,
    once you fix your code dealing with %kids, kill them explicitly.

    kill HUP => keys %kids.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Nov 30, 2005
    #10
  11. bsder

    Big and Blue Guest

    bsder wrote:

    >
    > I just want to follow C traditional style. There is no END style in C
    > anyway.


    Yes there is. It's called atexit(). (You might not have ever used it,
    but that's another matter).

    And what has C style got to do with programming in Perl anyway??? Do
    you declare all variable to be ints/floats/char etc???


    --
    Just because I've written it doesn't mean that
    either you or I have to believe it.
     
    Big and Blue, Dec 2, 2005
    #11
    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,130
    David Schwartz
    Dec 9, 2003
  2. Uwe Kubosch
    Replies:
    5
    Views:
    223
    Gary Wright
    Feb 2, 2008
  3. Noel Dolan
    Replies:
    0
    Views:
    236
    Noel Dolan
    Jul 18, 2004
  4. Paul Clements
    Replies:
    2
    Views:
    200
    Ben Morrow
    Feb 11, 2004
  5. Bitswapper
    Replies:
    5
    Views:
    148
    Prasad, Ramit
    Aug 27, 2013
Loading...

Share This Page