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

denkfehler? waitpid killt meinen Elternprozess...

Leser: 2


<< >> 2 Einträge, 1 Seite
Wlet
 2006-06-21 11:28
#67467 #67467
User since
2006-05-24
15 Artikel
BenutzerIn
[default_avatar]
Hallo,

ich bin gerade dabei einen kleinen SMTP-Server zu schreiben. Jetzt habe ich ein Problem mit dem Forking des Prozesses.

Das ganze lief bereits, aber die Prozessliste lief mir mit Zombies voll. Also wollte ich die wie hier beschrieben die Zombies automatisiert per Signalhandler abräumen lassen.
Dummerweise killt mir der Signalhandler aber meinen Elternprozess und den Kindprozess.

So hänge ich funktionalität an den Signalhandler...
Code: (dl )
1
2
3
4
5
6
7
sub sigchldHandler {
while (0 < (my $child = wait())) {
print STDOUT2 "closed Child: ".$child."\n";
}
}

$SIG{CHLD} = \&sigchldHandler;


Das ist meine Forkschleife:

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
while($conn = $Net::SMTP::Server::server->accept())
{
# Wenn eine Verbindung durch einen Client aufgebaut wurde wird der SMTP-Server geforked
my $kidpid = fork();
if (not defined $kidpid)
{
die "Cannot fork: $!";
} elsif ($kidpid == 0)
{
# fork gab Null zurück, also ist dies hier das "Neugeborene"
# die Abarbeitung beginnt
print STDOUT "Kindprozess: ".$$."\n";
my $client;
$Net::SMTP::Server::Client::client = new Net::SMTP::Server::Client($conn) ||
croak(getTime()." Unable to handle client connection: $!\n");
$Net::SMTP::Server::Client::client->process();
$from = $Net::SMTP::Server::Client::client->{FROM};
@to = $Net::SMTP::Server::Client::client->{TO};
$msg = "blubb";
$msg = decode_qp($msg);
@mail = split(/\n/,$msg);
# Convert a Mail::Internet object to a MIME::Entity:
$parser->output_under("/tmp");
$parser->decode_bodies(0);
$entity = new MIME::Entity;
$entity = $parser->parse_data($msg);
exit(0);
}else{
print STDOUT "Vaterprozess: ".$$."\n";
}
}


dann mache ich eine Telnetsession auf den geöffneten Port, was einwandfrei funktioniert.
Beende ich die Telnetsession ganz normal, d.h. es wird "exit(0);" erreicht, habe ich folgende Ausgabe:

Code: (dl )
1
2
3
4
linux:~/forwarder# ./Mailer.pl
Kindprozess: 28551
Vaterprozess: 28549
closed Child: 28551


Das Programm wird dann abgebrochen, und sowohl Vater als auch Kindprozess sind aus der Prozessliste verschwunden...

Was mache ich denn falsch?

danke für eure Hilfe...

Wlet\n\n

<!--EDIT|Wlet|1150876703-->
Wlet
 2006-06-21 12:22
#67468 #67468
User since
2006-05-24
15 Artikel
BenutzerIn
[default_avatar]
So,

mittlerweile habe ich eine Lösung für mein Problem gefunden:

Ich setze den Signahandler auf IGNORE, dann kümmert sich das Unix um das aufräumen.

Code: (dl )
$SIG{CHLD} = 'IGNORE';


perlipc

Quote
On most Unix platforms, the "CHLD" (sometimes also known as "CLD") signal has special behavior with
respect to a value of 'IGNORE'. Setting $SIG{CHLD} to 'IGNORE' on such a platform has the effect of
not creating zombie processes when the parent process fails to "wait()" on its child processes (i.e.
child processes are automatically reaped). Calling "wait()" with $SIG{CHLD} set to 'IGNORE' usually
returns "-1" on such platforms.


Kaum macht mans richtig, geht's ;)

Wlet
<< >> 2 Einträge, 1 Seite



View all threads created 2006-06-21 11:28.