Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re^4: Monitoring Child Process

by Anonymous Monk
on Oct 19, 2011 at 20:43 UTC ( #932496=note: print w/replies, xml ) Need Help??

in reply to Re^3: Monitoring Child Process
in thread Monitoring Child Process

Thank you very much. The normal condition works now where it is able to monitor the child process.

But the ctrl-c condition where I press the ctrl-c does not seem to be working. Maybe my testing is just wrong, but when I press ctrl-c, I do not see any other running child process.
while (@dead_kids < scalar @all_kids ) { print "dead kids: ", scalar @dead_kids, "\n";; sleep 1; # This is where I want to test the ctrl-c. sleep 5 if ( @dead_kids > 1 ); }

Replies are listed 'Best First'.
Re^5: Monitoring Child Process
by Marshall (Abbot) on Oct 20, 2011 at 01:28 UTC
    Ok, I'm back from my meeting and wrote some more code for you.

    Some changes:
    - while ( sleep(1), @dead_kids < @all_kids) {} will wait until the number of dead_kids is the same as all_kids. note: scalar in front of @all_kids is redundant. I've used both of these arrays in a scalar context. The sleep() is so that we don't burn CPU while looping. Handling SIGCHLD seems to prematurely end the sleep, but this code restarts the sleep if we aren't done. In Perl I think sleep() is implemented in terms of alarm() and I will admit something a bit weird is going on here that I don't fully understand although my workaround appears to be fine.

    - the $SIG{INT} = 'IGNORE'; in the child code is important. If you leave it in there, then hitting CTL-C will print the the currently running kids and then resume normal operation. If you comment that line out, then normal CTL-C handling is in effect for the children and they will exit. The CTL-C handler is only installed for the parent. The child either ignores CTL-C or has normal handling for it. On my Linux test machine, when this code is running in the foreground, everybody (all kids and the parent) get CTL-C if I hit that.

    Interesting problem. Have fun with this code. I didn't worry about efficiency in sub ctlc - I think the main point here is how to handle the signals and what to do when.

    #!/usr/bin/perl -w use strict; use POSIX qw(:sys_wait_h); $SIG{CHLD} = \&REAPER; $|=1; #turn off STDOUT buffering my (@all_kids, @dead_kids); my @array = qw(a b c d e f g h); for (1 .. 10) { die "Bad Fork! $!\n" if ( !defined(my $pid = fork()) ); if ($pid ==0) #I'm child { $SIG{INT} = 'IGNORE'; #### comment out to exit on CTL-C my $t = int(rand(5))+1; print "@array sleeping $t secs\n"; sleep ($t); exit (0); } push (@all_kids, $pid); #I'm parent print "Started another child process - $pid.\n"; } print "All child processes have started...\n"; print "kids are: @all_kids\n"; $SIG{INT} = \&ctlc; #CTL-C handler in parent only while ( sleep(1), @dead_kids < @all_kids) {} #wait for kids to finish print "dead kids: @dead_kids\n"; print "All child processes are finished\n"; sub REAPER { my $pid; while ( ($pid = waitpid(-1, WNOHANG)) > 0) { print "Process $pid exited.\n"; push @dead_kids, $pid; } } sub ctlc { print "***** Ctrl-C Trap\n"; my %dead = map{$_ => 1}@dead_kids; print "still alive: "; foreach my $kid (@all_kids) { print "$kid " if !$dead{$kid}; } print "\n"; print "***** Ctrl-C Trap end\n"; }
      Thank you very much. I didn't notice your reply as I was trying and playing with your code. I will test this tomorrow and will let you know.
        I did test my most recent code on a 64 bit, 4 core Linux machine running Active State 5.12. I claim that it "works as advertised" on my test machine.

        Run the code and see what happens...

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://932496]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2018-01-19 02:17 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (215 votes). Check out past polls.