Hallo,
folgendes Skript als Ausgangslage:
#v+
#!/usr/bin/perl
use warnings;
use strict;
use Time::HiRes qw ( sleep time );
if ( ( $#ARGV ) != 3 ) {
usage();
exit 1;
}
my $server = shift;
my $runtime = shift;
my $delay = shift;
my [at] intervals = split(/,/, shift);
my $debug = 1;
my $dryrun = 1;
$SIG{CHLD} = \&reaper;
my $children = 0;
sub usage {
print STDERR "Usage: $0 <server> <runtime> <delay> <intervals>\n\n";
print STDERR " <delay> is delay between runs with different interval\n";
}
sub reaper {
my $ch_pid;
$ch_pid = wait;
$children--;
$debug && warn time.": Reaped child with PID $ch_pid, $children children still running\n";
if ( $children == 0 ) {
$debug && warn time.": All children returned, exiting\n";
exit 0
}
$SIG{CHLD} = \&reaper;
}
sub testrun {
# gekuerzt, weil m.E.n. unwichtig
}
sub spawntest {
my $pid;
$pid = fork;
if ( $pid == 0 ) {
$debug && warn time.": Forked child with PID $$\n";
if ( $dryrun ) {
sleep 25;
} else {
testrun( [at] _);
}
exit;
} elsif ( undef $pid ) {
die "Error while forking\n";
} else {
$children++;
return;
}
}
# main
foreach my $ival ( [at] intervals ) {
my $numruns = $runtime / $ival;
my $run = 1;
while ( $run <= $numruns ) {
$debug && warn time.": Run $run of $numruns\n";
spawntest($ival);
$debug && warn time.": Sleeping for $ival\n";
sleep $ival;
$run++;
}
$debug && warn time.": Delaying for $delay\n";
sleep $delay;
}
$debug && warn time.": Still waiting for $children children\n";
while ( $children > 0 ) {
sleep 1;
}
exit 0;
#v-
Das Skript soll einen Test auf einem Webserver fahren (das passiert in
tESTRun, die Details sind glaub ich nicht relevant, da sich das Skript
auch im dryrun ohne Aufruf der Funktion testrun() gleich verhaelt),
dabei wird in der Hauptschleife fuer alle uebergebenen Intervalle die
Anzahl der Durchlaeufe aus der Runtime pro Intervall errechnet und
danach die Funktion fuer den fork aufgerufen. Funktioniert alles soweit
wunderbar (bin trotzdem fuer alle Tipps usw. dankbar, so oft programmier
ich nun auch wieder nicht Perl ;).
Mein Problem ist nun folgendes: manchmal wenn ein Kindsprozess
eingesammelt wird ueber die reaper-Funktion wird auch sofort das
naechste Kind mittels fork in die Welt gesetzt: (Ausgabe eines dryruns,
d.h. ohne Aufruf von testrun())
1141897377.19638: Reaped child with PID 14729, 8 children still running
1141897377.1965: Run 18 of 60
1141897377.19685: Forked child with PID 14868
1141897377.19713: Sleeping for 3
1141897378.0742: Reaped child with PID 14731, 8 children still running
1141897378.07432: Run 19 of 60
1141897378.07465: Forked child with PID 14870
1141897378.07492: Sleeping for 3
Das fuehrt natuerlich bei laengeren Tests massiv dazu, dass das
Intervall nicht mehr eingehalten wird.
Hat jemand eine Idee warum es zu diesem Verhalten kommt?
Danke schon mal im voraus.
lg
WK
--
____________________________________________________________ __________
Wolfgang Karall mailto: wolfgang.karall [at] spiney.org GPG: 0x172CC057
GPGKey fingerprint: F11F 50F8 96B7 C8B5 6D25 AEDE BA1C 0955 172C C057
- Student of Computer Science at the Vienna University of Technology -
