in reply to Child process dies

There's presumably a communication channel (a pipe?) between the parent and the child. You could periodically check the status of the communication channel.

If your communication channel is a pipe, then all you have to do is suicide when you receive a SIGPIPE signal. I think that might even be the default action! (This won't work in Windows.)

Replies are listed 'Best First'.
Re^2: Child process dies
by johngg (Canon) on Jan 05, 2007 at 15:51 UTC
    I was trying that but I can't seem to make it work. I kill (-15) the parent but the child carries on regardless. I have made the parent the reader and child the writer and have tried it the other way around. I'm using a short sleep in a loop in the child to mimic periodic activity. Using Perl 5.8.4 on SPARC/Solaris 9. Here's the script.

    use strict; use warnings; use IO::Pipe; $SIG{PIPE} = sub {exit;}; print qq{Parent PID $$\n}; my $pipeFH = IO::Pipe->new(); my $pid; if ($pid = fork) { $pipeFH->writer(); print qq{Kid is PID $pid\n}; } elsif(defined($pid)) { $pipeFH->reader(); sleep 1 for 1 .. 100; exit; } while ((my $returnPid = wait) != -1) { print qq{Kid $returnPid returned\n}; }

    Maybe there is a flaw in my attempt.

    Cheers,

    JohnGG

    Update: The flaws in my attempts were twofold. Firstly, frodo72 pointed out that the SIGPIPE would not be generated until the child process tried to do I/O on the pipe that had been closed at the other end because the parent had been killed. Secondly, it appears that IO::Pipe is somehow consuming the SIGPIPE before the child sees it so the child carries on oblivious to it's parent's death. Again, frodo72 discovered this by refactoring my code to use pipe instead of IO::Pipe.

    frodo72 ++ and thanks for all the help.

      IIRC the SIGPIPE signal should be sent only when the one end tries to do I/O on a pipe that is closed on the other end. Moreover... why sleep 1 for 1 .. 100; instead of sleep 100;?

      Flavio
      perl -ple'$_=reverse' <<<ti.xittelop@oivalf

      Don't fool yourself.
        Why the sleep 1 for 1 .. 100;? My ignorance really; I wasn't sure whether the script, like my daughter, would sleep through the alarm so I decided to try lots of small sleeps after it didn't work with one long sleep.

        I was already trying things like explicitly closing the pipe in the parent if it caught a signal. Following your post I have modified the script so the child keeps printing a "heartbeat" to the pipe but still to no avail. Here's the modified script.

        use strict; use warnings; use IO::Pipe; my $pipeFH; my $rcHandler = sub {$pipeFH->close(); exit;}; $SIG{INT} = $rcHandler; $SIG{QUIT} = $rcHandler; $SIG{TERM} = $rcHandler; print qq{Parent PID $$\n}; $pipeFH = IO::Pipe->new(); my $pid; if ($pid = fork) { $pipeFH->reader(); print qq{Kid is PID $pid\n}; } elsif(defined($pid)) { $SIG{PIPE} = sub {exit;}; $pipeFH->writer(); $pipeFH->print(qq{Kid: Snoozing\n}); for my $heartbeat ( 1 .. 30 ) { $pipeFH->print(qq{Kid: Heartbeat $heartbeat\n}); sleep 1; } $pipeFH->print(qq{Kid: Waking\n}); print qq{Kid: Quitting\n}; exit; } while ((my $returnPid = wait) != -1) { print qq{Kid $returnPid returned\n}; } while (defined(my $line = $pipeFH->getline())) { print qq{Read: $line}; }

        I had been killing the parent with a kill -15 (TERM) from another shell but I noticed that the child does go away immediately if I Ctrl-C the running parent. Is it the case that child processes also get an INT if the parent gets one from the shell?

        Cheers,

        JohnGG

Re^2: Child process dies
by sgifford (Prior) on Jan 06, 2007 at 01:33 UTC
    A variation on this is to write the whole thing in a select loop, which waits for the filehandle from the parent to become readable and any other conditions. The parent filehandle will become readable as soon as it exits, and a read will return an end-of-file indicator.