Bloehdian has asked for the wisdom of the Perl Monks concerning the following question:
Hello Monks,
I wrote a test application in which the process is forked. The resulting parent process sends a message continuously via pipe using syswrite to the child.
I installed a signal handler in the parent for signal SIGHUP, so that I can "advice" the parent from the command line to terminate the child (on sending SIGHUP to the parent process). At least I try to do this.
Here is the code:
use strict; use warnings; use Errno qw( EWOULDBLOCK ) ; my $from_parent; my $to_child; my $pid; my $mesg_parent = "Hello Child!"; my $mesg_child; my $test; pipe( $from_parent, $to_child ); if ( $pid = fork() ) { # Parent $SIG{ HUP } = sub{ kill( 15 , $pid ); print( "KILLED CHILD!!!\n" ) +}; close( $from_parent ); while ( 1 ) { eval{ $test = syswrite( $to_child, $mesg_parent, length( $mesg_p +arent ) ); }; select( undef, undef, undef, .5); if ( $@ ) { print( "trapped error when writing to pipe \$to_child_ssl\n" +); next; } if ( defined $test ) { print( "Sent message \"$mesg_parent\" to child\n" ); } } } else { # Child close( $to_child ); while ( 1 ) { $test = sysread( $from_parent, $mesg_child, 13 ); select( undef, undef, undef, .5 ); if ( ! defined $test ) { if ( $! == EWOULDBLOCK ) { print( "sysread would be blocked by \$from_parent: $!\n" ) +; next; } else { die ( "Error when trying to read from \$from_parent: $!\n" + ); } } print( "In child\n" ); print( $mesg_child . "\n" ); $mesg_child =~ s/Child/Parent/; print $mesg_child . "\n"; } }
When I run the script and execute
kill -1 <pid>in a different terminal window with <pid> being the parent process's PID than the final output is as follows:
Sent message "Hello Child!" to child In child Hello Child! Hello Parent! Sent message "Hello Child!" to child In child Hello Child! Hello Parent! KILLED CHILD!!! Sent message "Hello Child!" to child Sent message "Hello Child!" to child xyz@v32470:~/projekte/$
i.e., not only the child´, but the parent as well is terminated.
If I use
kill 1 <pid>then obviously only the parent process is killed, the child continues to run:
In child Hello Child! Hello Parent! Terminated xyz@v32470:~/projekte$ In child Hello Child! Hello Parent! In child In child In child In child
The kill command comes back with an error message btw:
xyz@v32470:~$ kill 1 31055 -bash: kill: (1) - Operation not permitted
How can this behaviour explained and how could I reach that only the child is killed by the parent and the parent continues to work?
The backgroud: I want to use this code as the basis for a script in which the parent checks whether the child is still running by sending messages via pipe to the child and checks the response (i.e., in the final version the communication would be bidirectional).
Is this feasible using this approach at all?
From my ´point of view it boils down to the qestion whether I could trap an error as indicated in the script when trying to syswrite() to the üipe after the child passed away. Is this possible?
Cheers Bloehdian
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: fork(): terminating the child without killing the parent
by tybalt89 (Monsignor) on Oct 26, 2016 at 04:02 UTC | |
|
Re: fork(): terminating the child without killing the parent
by hippo (Archbishop) on Oct 26, 2016 at 08:05 UTC | |
|
Re: fork(): terminating the child without killing the parent
by tybalt89 (Monsignor) on Oct 26, 2016 at 03:21 UTC |