Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]4461[/thread]

system()-Aufruf in einem Kindprozess eines Servers

Leser: 1


<< >> 7 Einträge, 1 Seite
MickiM2000
 2007-04-19 17:01
#37507 #37507
User since
2007-04-19
4 Artikel
BenutzerIn
[default_avatar]
Hallo,

zum Einsammeln der Zombies bei einem Server, der durch fork mehrere Kindprozesse erzeugt, benutze ich die sub REAPER. Nun möchte ich aber in den Kindprozessen auch externe Programme über system() starten und den Rückgabewert auswerten. Dies funktioniert aber nicht bei der Nutzung des REAPERS. Welche Lösung habt ihr dafür?

reduzierter Beispielcode:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use strict;
use warnings;
use POSIX;
use POSIX "sys_wait_h";

local $SIG{CHLD} = \&REAPER;

my $wert = system('ls');
print "Rueckgabe: $wert\n";

if ($wert == 0) {
print "Ok\n";
}
else {
print "Fehler\n";
}
exit 0;

sub REAPER {
my $sig = shift;
my $pid;
while (($pid = waitpid(-1, WNOHANG)) > 0) {
print "child $pid terminated - status $?\n";
print "sig: $sig\n";
}
$SIG{CHLD} = \&REAPER;
}


Gruß
MickiM2000
ptk
 2007-04-20 01:17
#37508 #37508
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Vielleicht kannst du dort $SIG{CHLD} wieder auf DEFAULT setzen?
betterworld
 2007-04-20 04:25
#37509 #37509
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Bei mir gibt Dein Programm das aus:
Code: (dl )
1
2
Rueckgabe: 0
Ok

Der Reaper wird offenbar zwar aufgerufen, kriegt aber nichts zurueck bei waitpid.
Wie moechtest Du, dass sich das Programm stattdessen verhaelt?
bloonix
 2007-04-20 12:17
#37510 #37510
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Wird der Child-Prozess bei system() nicht von der Shell eingesammelt?
Denn die Shell, die mit system() erzeugt wird und den Befehl ausführt ist
ja auch der Parent Prozess. wait() liefert zum Beispiel -1 zurück, was soviel
bedeutet wie das der Prozess schon automatisch "reaped" wurde.

Allerdings ist der REAPER nicht schlecht, da er wohl die Shell einsammelt,
wenn die mal hängen sollte?\n\n

<!--EDIT|opi|1177057169-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
betterworld
 2007-04-20 13:20
#37511 #37511
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
[quote=opi,20.04.2007, 10:17]Allerdings ist der REAPER nicht schlecht, da er wohl die Shell einsammelt,
wenn die mal hängen sollte?[/quote]
Sie wird immer automatisch eingesammelt, sonst koennte $? nicht gesetzt sein.

Aber in unserem Fall gibt es übrigens keine Shell.  system startet nur eine Shell, wenn der Befehl Sonderzeichen enthalt.  ls wird aber in diesem Fall direkt gestartet.\n\n

<!--EDIT|betterworld|1177060947-->
bloonix
 2007-04-20 14:08
#37512 #37512
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Nun, dann würde ich eher diese Variante bevorzugen:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use strict;
use warnings;
use POSIX ":sys_wait_h";

$SIG{CHLD} = \&REAPER;

my @commands = qw/ls w id/;
my %childs   = ();
my %reaped   = ();

foreach my $cmd (@commands) {
  if (my $pid = fork) {
     $childs{$pid} = '';
  } else {
     # 1 sekunde warten, da es sein kann, dass $childs{$pid}
     # erst gesetzt wird, wenn der Child schon gestorben ist
     sleep 1;
     my $foo = qx{$cmd};
     exit($?/256);
  }
}

# solange schlafen, bis alle Childs eingesammelt wurden
sleep while scalar keys %childs;

print "child $_ terminated - status $reaped{$_}\n"
  foreach sort keys %reaped;

sub REAPER {
  my $sig = shift;
  my $pid;
  while (($pid = waitpid(-1, WNOHANG)) > 0) {
     delete $childs{$pid};
     $reaped{$pid} = $sig.':'.$?;
  }
  $SIG{CHLD} = \&REAPER;
}


#> ./test.pl
child 25145 terminated - status CHLD:0
child 25146 terminated - status CHLD:0
child 25147 terminated - status CHLD:0


Auf diese Weise handelt jeder Child den Systemcall selber und gibt den
Status über CHLD an den Parent zurück.\n\n

<!--EDIT|opi|1177063997-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
bloonix
 2007-04-20 14:19
#37513 #37513
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
oder auch so, um genauere Infos über das ausgeführte Kommando jedes
Childs zu erfahren:

Code: (dl )
1
2
3
4
5
6
7
8
...
  if (my $pid = fork) {
     $childs{$pid} = $cmd;
  }
  ...
  $reaped{$pid} = $childs{$pid}.':'.$sig.':'.$?;
  delete $childs{$pid};
...


child 25833 terminated - status ls:CHLD:0
child 25834 terminated - status w:CHLD:0
child 25835 terminated - status id:CHLD:0
\n\n

<!--EDIT|opi|1177064389-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
<< >> 7 Einträge, 1 Seite



View all threads created 2007-04-19 17:01.