Frage zu fork, SIGCHLD und Timing im Elternprozess

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 -
Wolfgang Karall [ Do, 09 März 2006 10:12 ] [ ID #1222712 ]

Re: Frage zu fork, SIGCHLD und Timing im Elternprozess

Wolfgang Karall schrieb:

> Hallo,
>

> sleep $ival;

> 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:

> Hat jemand eine Idee warum es zu diesem Verhalten kommt?

Vielleicht, weil das SIGCHLD den system call sleep(2) abbricht.
perldoc -f sleep
Ingo Menger [ Do, 09 März 2006 11:16 ] [ ID #1222713 ]

Re: Frage zu fork, SIGCHLD und Timing im Elternprozess

On 2006-03-09 10:16:52, Ingo Menger <quetzalcotl [at] consultant.com> wrote:
> Vielleicht, weil das SIGCHLD den system call sleep(2) abbricht.
> perldoc -f sleep

Danke, auch wenn ich nicht frei aus dem Kopf "such as SIGALRM" mit
SIGCHLD in Verbindung gebracht haette. Ich hab's jetzt auf jeden Fall
mit dem Rueckgabewert von sleep geloest und leg den Elternprozess im
Anlassfall einfach solange nochmal schlafen bis mindestens das Intervall
vergangen ist.

Gibt's sonst bez. des Skripts qualitativ noch Probleme?

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 -
Wolfgang Karall [ Do, 09 März 2006 13:35 ] [ ID #1222714 ]

Re: Frage zu fork, SIGCHLD und Timing im Elternprozess

Wolfgang Karall schrieb:

> On 2006-03-09 10:16:52, Ingo Menger <quetzalcotl [at] consultant.com> wrote:
> > Vielleicht, weil das SIGCHLD den system call sleep(2) abbricht.
> > perldoc -f sleep
>
> Danke, auch wenn ich nicht frei aus dem Kopf "such as SIGALRM" mit
> SIGCHLD in Verbindung gebracht haette.

Meines Wissens bricht jedes Signal einen "langen" system call ab. Bei
der Frage, was ein langer system call ist, hilft ein bischen die
Intuition. getpid(2) z.B. sicher nicht.
Im Zweifel hilft die in Frage stehende Manual-Seite. Ist dort als
Fehlermöglichkeit EINTR angegeben, ist es einer.
Ingo Menger [ Do, 09 März 2006 14:48 ] [ ID #1222716 ]

Re: Frage zu fork, SIGCHLD und Timing im Elternprozess

On 2006-03-09 13:48:04, Ingo Menger <quetzalcotl [at] consultant.com> wrote:
> Im Zweifel hilft die in Frage stehende Manual-Seite. Ist dort als
> Fehlermöglichkeit EINTR angegeben, ist es einer.

Ah, ok, in nanosleep(2) seh ich EINTR. Danke fuer die Ausfuehrungen.

In meinem Skript hab ich jetzt noch die reaper-sub nach Studium des
perlipc Manuals mit while-Schleife und der Funktion waitpid geloest,
damit gehen mir jetzt auch keine Kindchen mehr verloren wenn sie
"zeitgleich" eintrudeln.

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 -
Wolfgang Karall [ Do, 09 März 2006 15:35 ] [ ID #1222719 ]
Perl » de.comp.lang.perl.misc » Frage zu fork, SIGCHLD und Timing im Elternprozess

Vorheriges Thema: Datenbank-Abfrage von illegalen Zeichen befreien
Nächstes Thema: Match zwei Reihen