D
deoquinn
Hello all, I have a a need to use backticks in a forked child while
running many simultaneous children (on Windows). This is a pinging
application, so, I am pinging multiple hosts and capturing their ping
response time as shown below.... The problem is that I can *only* get
this to work if I move the 'child' code to another script and then
'exec(....)' that script, which is turning out to be *very* expensive
and slow... If I run it as coded, it hangs after the first (sometimes
first couple of) forks. Do I need to do something with STDIN/STDOUT
(or something else) in the child here? I have tried several different
ways of doing this (including using Net:ing ( with external protocol
and HiRes ) but it didn't perform very well nor behave like I wanted -
plus, I will be running this on multiple systems and do not want to
have to install more modules everywhere and keep them up to date, so,
I'd like to leave that out)...
So... The question is... How do the system calls happen in the
forked children and why is such a call hanging the script? The
platform is Windows Server 2003 and the perl vers is 5.8.8 Build 820.
Thanks to any responders....
foreach $host ( sort { uc($a) cmp uc($b) } keys %hosts ) {
my $pid;
# throttle back the spawning to limit impact on system
if ( $throttle++ > 20 ) { sleep 5; $throttle = 0; }
FORK: {
if ( $pid = fork ) {
# Parent
# Harvest a few finished children if existent....
waitpid(-1,WNOHANG);
next; # go get next host and fork again...
}
elsif ( defined $pid ) {
# Child
my $avg = -1;
for ( my $i = 1; $i < 4 && $avg == -1; $i++ ) {
$wait = $i*1000;
foreach ( reverse (`ping -w 1000 -n 1 $host`) )
{ ###### BACKTICKS HERE
last if $avg != -1 || $? > 0;
# Get the avg ping response time only - implied ping
failure is $avg is not changed from -1
if ( m/Average\s=\s/ ) { ( $avg = $_ ) =~ s/^.*?Average\s=
\s(\d+).*\n*$/$1/ }
}
}
print "\Child: Average $host - $avg ms\n";
}
elsif ( $! == EAGAIN ) {
# Sleep a little and Harvest orphaned children before retrying
fork....\n";
sleep 5;
wait();
redo FORK;
}
else { die "Unrecoverable Fork Error: $!" }
} # end FORK Label
} # end FOREACH loop
exit;
running many simultaneous children (on Windows). This is a pinging
application, so, I am pinging multiple hosts and capturing their ping
response time as shown below.... The problem is that I can *only* get
this to work if I move the 'child' code to another script and then
'exec(....)' that script, which is turning out to be *very* expensive
and slow... If I run it as coded, it hangs after the first (sometimes
first couple of) forks. Do I need to do something with STDIN/STDOUT
(or something else) in the child here? I have tried several different
ways of doing this (including using Net:ing ( with external protocol
and HiRes ) but it didn't perform very well nor behave like I wanted -
plus, I will be running this on multiple systems and do not want to
have to install more modules everywhere and keep them up to date, so,
I'd like to leave that out)...
So... The question is... How do the system calls happen in the
forked children and why is such a call hanging the script? The
platform is Windows Server 2003 and the perl vers is 5.8.8 Build 820.
Thanks to any responders....
foreach $host ( sort { uc($a) cmp uc($b) } keys %hosts ) {
my $pid;
# throttle back the spawning to limit impact on system
if ( $throttle++ > 20 ) { sleep 5; $throttle = 0; }
FORK: {
if ( $pid = fork ) {
# Parent
# Harvest a few finished children if existent....
waitpid(-1,WNOHANG);
next; # go get next host and fork again...
}
elsif ( defined $pid ) {
# Child
my $avg = -1;
for ( my $i = 1; $i < 4 && $avg == -1; $i++ ) {
$wait = $i*1000;
foreach ( reverse (`ping -w 1000 -n 1 $host`) )
{ ###### BACKTICKS HERE
last if $avg != -1 || $? > 0;
# Get the avg ping response time only - implied ping
failure is $avg is not changed from -1
if ( m/Average\s=\s/ ) { ( $avg = $_ ) =~ s/^.*?Average\s=
\s(\d+).*\n*$/$1/ }
}
}
print "\Child: Average $host - $avg ms\n";
}
elsif ( $! == EAGAIN ) {
# Sleep a little and Harvest orphaned children before retrying
fork....\n";
sleep 5;
wait();
redo FORK;
}
else { die "Unrecoverable Fork Error: $!" }
} # end FORK Label
} # end FOREACH loop
exit;