The problem with pipes is that you can kill your child, or the child hangs or takes too long, without the parent knowing, as it is "reading". So you need an alarm ($SIG{'ALRM'}) in your parent. A way I do it (so the parent stays responsive)
#!/usr/bin/perl use strict; use warnings; my $parent_pid = $$; my $child_pid = 0; my @child_output; my $read_from_child = 0; my $max_timeout = 60; my $timeout; print "Parent is $parent_pid\n"; my $pid = open(KID_TO_READ, "-|"); defined($pid) || die "can't fork: $!"; #local $SIG{CHLD}; if ($pid) { # parent local $SIG{'CHLD'} = sub { print "dead child\n"; $timeout=0 }; local $SIG{'USR1'} = sub { ++$read_from_child }; print "reading kid...\n"; $timeout = $max_timeout; while($timeout >0){ print "parent $parent_pid timeout=$timeout read_from_child=$re +ad_from_child - child_pid=$child_pid\n"; if($read_from_child>0){ --$read_from_child; $_=<KID_TO_READ>; print "parent $$ just read: $_"; unless( $child_pid>0 ){ chomp($child_pid = $_); }else{ push @child_output, $_; } }else{ sleep 1; --$timeout; } } close(KID_TO_READ); } else { # child print $$ . "\n"; # send child pid kill('USR1', $parent_pid); # warn parent there is data print STDERR "child $$ is running\n"; # print to screen (DEBUG) my $program = "/bin/sleep"; my @args = qw(3); my $ret = system($program, @args); print "returncode is $ret\n"; # is $? print STDERR "returncode is $ret\n"; # print to screen (DEBUG) kill('USR1', $parent_pid); # warn parent there is data exit 0; } print "\nChild $child_pid is done, we now have:\n@child_output\n";
which prints something like:
Parent is 5323 reading kid... parent 5323 timeout=60 read_from_child=0 - child_pid=0 child 5324 is running parent 5323 timeout=59 read_from_child=1 - child_pid=0 parent 5323 just read: 5324 parent 5323 timeout=59 read_from_child=0 - child_pid=5324 parent 5323 timeout=58 read_from_child=0 - child_pid=5324 parent 5323 timeout=57 read_from_child=0 - child_pid=5324 parent 5323 timeout=56 read_from_child=0 - child_pid=5324 returncode is 0 parent 5323 timeout=55 read_from_child=1 - child_pid=5324 parent 5323 just read: returncode is 0 parent 5323 timeout=55 read_from_child=0 - child_pid=5324 dead child Child 5324 is done, we now have: returncode is 0
See also:
Re: How to make parent wait for all the child processes.
In reply to Re: get same return that system gives and get pid
by FreeBeerReekingMonk
in thread get same return that system gives and get pid
by Raiden690
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |