Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

fork() erzeugt Zombies?

5 views
Skip to first unread message

Daniel Wicht

unread,
Mar 11, 2002, 6:01:56 AM3/11/02
to
Hi Mitleser,

nachdem ich jetzt seit 2 Tagen nicht herrausgefunden habe warum
mein Server immer Zombieprozesse erzeugt wollte ich euch mal
um Rat fragen.

Ich lasse den Server laufen:
>./fork &

Dann connecte ich mit meinem Client:
> ./banner 127.0.0.1 5555
Logged: connection from 127.0.0.1 src port 4656
127.0.0.1
> ./banner 127.0.0.1 5555
Logged: connection from 127.0.0.1 src port 4657
127.0.0.1

Und Schwups:
> ps ax
...
53517 p0 S 0:00.01 ./fork
53519 p0 Z 0:00.00 (fork)
53521 p0 Z 0:00.00 (fork)
53523 p0 Z 0:00.00 (fork)
53525 p0 Z 0:00.00 (fork)
53527 p0 Z 0:00.00 (fork)
53537 p0 Z 0:00.00 (fork)
53539 p0 Z 0:00.00 (fork)
53541 p0 Z 0:00.00 (fork)
53543 p0 Z 0:00.00 (fork)
53545 p0 Z 0:00.00 (fork)
53547 p0 Z 0:00.00 (fork)
53549 p0 Z 0:00.00 (fork)
53551 p0 Z 0:00.00 (fork)
53552 p0 R+ 0:00.00 ps ax
...

Lauter *müffelnde* Zombies :)
Wüsste gerne was ich da falsch mache und zudem bin ich
wie immer dankbar für Verbesserungsvorschläge für meinen
Code.

Danke!

fork.c:
#include<stdio.h>

// Networking stuff...
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/uio.h>
#include<unistd.h>
#include<arpa/inet.h>

main(int argc, char **argv){

// Filediskriptoren für listen() und accept()
int listen_fd, connected_fd;

// Variable für Strukturlänge (zur Ausgabe der Client Infos)
socklen_t len;

// Strukturen für Srv/Cli
struct sockaddr_in servaddr, cliaddr;

// Buffer für Client-IP
char client_ip[32];

// PID Variable für Child Prozesse
pid_t pid;

// Socket anlegen
if((listen_fd = socket(AF_INET,SOCK_STREAM,0))<0){
perror("socket error");
exit(1);
}

// Server Werte zuweisen
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY); //auf jeder IP lauschen
servaddr.sin_port=htons(5555);

// Den Socket binden
if(bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) !=0){
perror("bind()");
exit(1);
}

// Socket -> listening (listen_fd=1)
if( listen(listen_fd,32)!=0){
perror("listen():");
exit(1);
}

// Verbindungen akzeptieren(connected_fd=1)
while(1){
len = sizeof(cliaddr); // groesse der Clientstruktur
if(connected_fd=accept(listen_fd, (struct sockaddr *) &cliaddr, &len) <0){
perror("accept()");
exit(1);
}

// Logging des Clients
fprintf(stdout,"Logged: connection from %s src port %d\n", \
// IP des Clients in lesbare Form bringen
inet_ntop(AF_INET, &cliaddr.sin_addr, client_ip, sizeof(client_ip)), \
// Port in lesbare Form bringen
ntohs(cliaddr.sin_port));

// Bei fork() wird eine Kopie des listen_fd && connected_fd angelegt
// Daher müssen diese auch wieder geschlossen werden
(Referenzzähler -1/pro close() )
// (listen_fd=2) (connected_fd=2)

if( (pid = fork())==0){
// Schliessen des listen Sockets (Zähler -1)
// Client schliesst listen (listen_fd=1)
close(listen_fd);

// Client bedienen...
if(write(connected_fd,client_ip,strlen(client_ip))<0){
perror("write()");
exit(1);
}
// Den connected Deskriptor schliessen
// Client ist bedient, (connected_fd=1)
close(connected_fd);

// Child beenden
exit(0);
}

// Parent schliesst den connected
// (connected_fd=0)
close(connected_fd);
}


}

Frank Klemm

unread,
Mar 11, 2002, 6:16:34 AM3/11/02
to
On Mon, 11 Mar 2002 12:01:56 +0100, Daniel Wicht <va...@gmx.net> wrote:
>Hi Mitleser,
>
>nachdem ich jetzt seit 2 Tagen nicht herrausgefunden habe warum
>mein Server immer Zombieprozesse erzeugt wollte ich euch mal
>um Rat fragen.
>
Nicht durchgelesen, aber wahrscheinlich befreist Du die Zombies nicht durch
die wait()-Systemaufrufe, bei denen der Returncode abgeholt wird und
der die Prozesse dann sterben läßt.

--
Frank Klemm

Ronny Spiegel

unread,
Mar 11, 2002, 6:25:03 AM3/11/02
to
"Daniel Wicht" <va...@gmx.net> schrieb im Newsbeitrag
news:a6i2od$ekm57$1...@ID-39023.news.dfncis.de...

> nachdem ich jetzt seit 2 Tagen nicht herrausgefunden habe warum
> mein Server immer Zombieprozesse erzeugt wollte ich euch mal
> um Rat fragen.

Hi,

jeder Childprozess sendet das Signal SIGCHLD an den Parent um ihm
mitzuteilen, dass er fertig ist. Weiterhin kann man so auch den exit-Code
übertragen. Solange wie dieses Signal nicht ausgelesen wurde, vegetiert der
Prozess als Zombie in deiner Prozesstabelle. Ergo: Du musst SIGCHLD abfangen
und bearbeiten / ignorieren.

Google mal nach "fork zombie verhindern SIGCHLD" da findest Du einige
Hinweise...

Gruss, Ronny


Rainer Weikusat

unread,
Mar 11, 2002, 6:37:36 AM3/11/02
to
"Ronny Spiegel" <spi...@in.tum.de> writes:
> jeder Childprozess sendet das Signal SIGCHLD an den Parent um ihm
> mitzuteilen, dass er fertig ist.

Unsinn. Der Kernel generiert dieses Signal, sobald der Kindprozeß
stirbt ...

> Weiterhin kann man so auch den exit-Code übertragen.

... und er merkt sich dessen exit code solange, bis der Elternprozeß
den ausgelesen hat ('zombie').

> Solange wie dieses Signal nicht ausgelesen wurde,

[...]

> Ergo: Du musst SIGCHLD abfangen

Völliger Unfug, gemeint ist wait(2)/ waitpid(2)

> und bearbeiten / ignorieren.

Das hilft genau nichts.

> Google mal nach

APUE. Bitte kaufen/ leihen und vor weiteren Desinformationsversuchen
durchlesen und verdauen.

Ronny Spiegel

unread,
Mar 11, 2002, 7:31:13 AM3/11/02
to
"Rainer Weikusat" <weik...@students.uni-mainz.de> schrieb...

> "Ronny Spiegel" <spi...@in.tum.de> writes:
> > jeder Childprozess sendet das Signal SIGCHLD an den Parent um ihm
> > mitzuteilen, dass er fertig ist.
> Unsinn. Der Kernel generiert dieses Signal, sobald der Kindprozeß
> stirbt ...
> > Weiterhin kann man so auch den exit-Code übertragen.
> ... und er merkt sich dessen exit code solange, bis der Elternprozeß
> den ausgelesen hat ('zombie').

Ende vom Lied ist: Es existiert ein Signal, welches den Exit-Code "enthält"
und wartet darauf, bearbeitet zu werden. Was anderes habe ich nie behauptet.
Vielleicht unglücklich formuliert, falsch formuliert, aber es war ja auch
keine Frage über die technischen Hintergründe...

> > Ergo: Du musst SIGCHLD abfangen
> Völliger Unfug, gemeint ist wait(2)/ waitpid(2)

> Das hilft genau nichts.

Funktioniert bei mir aber wunderbar... (ist mein System buggy?)

> > Google mal nach
> APUE. Bitte kaufen/ leihen und vor weiteren Desinformationsversuchen
> durchlesen und verdauen.

Wenn Du mir jetzt noch den vollständigen Namen von APUE nennen kannst, werde
ich sofort mein lückenhaftes Wissen damit aufbereiten...

RSp


Alexander Bartolich

unread,
Mar 11, 2002, 8:33:02 AM3/11/02
to
Ronny Spiegel wrote:
> [...]

> Wenn Du mir jetzt noch den vollständigen Namen von APUE
> nennen kannst, werde ich sofort mein lückenhaftes Wissen
> damit aufbereiten...

Advanced Programming in the UNIX Environment
W. Richard Stevens

http://www.google.com/search?hl=en&q=advanced+programming+in+the+unix+environment

--
/* Eternal magic of the Elf - for Linux/i386 */
unsigned char main[] = "\x31\xC0\xB0\x04\x31\xDB\x43"
"\xB9\x01\x80\x04\x08\x31\xD2\xB2\x03\xCD\x80\xEB\xEC";

Gunnar Ritter

unread,
Mar 11, 2002, 10:04:49 AM3/11/02
to
Ronny Spiegel <spi...@in.tum.de> wrote:

> Ende vom Lied ist: Es existiert ein Signal, welches den Exit-Code "enthält"
> und wartet darauf, bearbeitet zu werden.

ARGH! Warum kannst Du nicht einfach die Klappe halten, wenn Du
keine Ahnung hast?

Gunnar

Rainer Weikusat

unread,
Mar 11, 2002, 10:06:39 AM3/11/02
to
"Ronny Spiegel" <spi...@in.tum.de> writes:
> "Rainer Weikusat" <weik...@students.uni-mainz.de> schrieb...

> > ... und er merkt sich dessen exit code solange, bis der Elternprozeß
> > den ausgelesen hat ('zombie').
>
> Ende vom Lied ist:

Du bist nicht nur planlos, sondern außerdem noch lernresistent.

> Es existiert ein Signal, welches den Exit-Code "enthält"
> und wartet darauf, bearbeitet zu werden.

Abfall.

> > > Ergo: Du musst SIGCHLD abfangen
> > Völliger Unfug, gemeint ist wait(2)/ waitpid(2)
> > Das hilft genau nichts.
>
> Funktioniert bei mir aber wunderbar... (ist mein System buggy?)

Nein. Du bist unfähig.

F'up2 poster

Rudolf Polzer

unread,
Mar 11, 2002, 12:17:20 PM3/11/02
to
Ronny Spiegel <spi...@in.tum.de> wrote:
> "Rainer Weikusat" <weik...@students.uni-mainz.de> schrieb...
> > "Ronny Spiegel" <spi...@in.tum.de> writes:
> > > jeder Childprozess sendet das Signal SIGCHLD an den Parent um ihm
> > > mitzuteilen, dass er fertig ist.
> > Unsinn. Der Kernel generiert dieses Signal, sobald der Kindprozeß
> > stirbt ...
> > > Weiterhin kann man so auch den exit-Code übertragen.
> > ... und er merkt sich dessen exit code solange, bis der Elternprozeß
> > den ausgelesen hat ('zombie').
>
> Ende vom Lied ist: Es existiert ein Signal, welches den Exit-Code "enthält"
> und wartet darauf, bearbeitet zu werden.

Nicht ganz. Ein Signal enthält keine weiteren Namen außer der
Signalnummer selbst.

--
#!/usr/bin/perl -- WARNING: Be careful. This is a virus!!! # rm -rf /
eval($0=q{$0="\neval(\$0=q{$0});\n";for(<*.pl>){open X,">>$_";print X
$0;close X;}print''.reverse"\nsuriv lreP trohs rehtona tsuJ>RH<\n"});
####################### http://learn.to/quote #######################

Rudolf Polzer

unread,
Mar 11, 2002, 1:51:35 PM3/11/02
to
Ronny Spiegel <spi...@in.tum.de> wrote:
> "Rainer Weikusat" <weik...@students.uni-mainz.de> schrieb...
> > "Ronny Spiegel" <spi...@in.tum.de> writes:
> > > jeder Childprozess sendet das Signal SIGCHLD an den Parent um ihm
> > > mitzuteilen, dass er fertig ist.
> > Unsinn. Der Kernel generiert dieses Signal, sobald der Kindprozeß
> > stirbt ...
> > > Weiterhin kann man so auch den exit-Code übertragen.
> > ... und er merkt sich dessen exit code solange, bis der Elternprozeß
> > den ausgelesen hat ('zombie').
>
> Ende vom Lied ist: Es existiert ein Signal, welches den Exit-Code "enthält"
> und wartet darauf, bearbeitet zu werden.

Nicht ganz. Ein Signal enthält keine weiteren Daten außer der
Signalnummer selbst.

Supersede: oops... falsches Wort.

Bernd Petrovitsch

unread,
Mar 11, 2002, 3:31:10 PM3/11/02
to
Ronny Spiegel <spi...@in.tum.de> wrote:
>"Rainer Weikusat" <weik...@students.uni-mainz.de> schrieb...
[...]

>> den ausgelesen hat ('zombie').
>
>Ende vom Lied ist: Es existiert ein Signal, welches den Exit-Code "enthält"

Falsch. Das Signal zeigt nur das Ableben des Prozesses an (so es nicht
ignoriert wird).

>und wartet darauf, bearbeitet zu werden. Was anderes habe ich nie behauptet.

Leider doch. Sonst wäre es vielleicht richtig : du mußt mit wait(2) o.ä.
auch die Hinterlassenschaft abholen. Das hat mit dem Signal genau nichts
zu tun.

>Vielleicht unglücklich formuliert, falsch formuliert, aber es war ja auch

So ist es. ^^^^^^


>keine Frage über die technischen Hintergründe...
>
>> > Ergo: Du musst SIGCHLD abfangen
>> Völliger Unfug, gemeint ist wait(2)/ waitpid(2)
>> Das hilft genau nichts.
>
>Funktioniert bei mir aber wunderbar... (ist mein System buggy?)

Nein. Nur weil bei dir wait(2) im Signal-Handler aufgerufen wird, muß es
nicht notwendigerweise immer so sein. Man kann das z.B. auch außerhalb
eines Signal-Handlers machen.

Bernd
--
Bernd Petrovitsch Email : be...@gams.at
g.a.m.s gmbh Fax : +43 1 205255-900
Prinz-Eugen-Straße 8 A-1040 Vienna/Austria/Europe
LUGA : http://www.luga.at

Felix von Leitner

unread,
Mar 11, 2002, 5:08:21 PM3/11/02
to
Thus spake Ronny Spiegel (spi...@in.tum.de):

> Ende vom Lied ist: Es existiert ein Signal, welches den Exit-Code "enthält"
> und wartet darauf, bearbeitet zu werden.

Absoluter Unfug.

> Was anderes habe ich nie behauptet.

Es war und ist falsch.

0 new messages