Newsgroup: it.comp.os.linux.development
Titolo: Fork() & Zombie . Vi capita ??

Salve a tutti.
Ho riscontrato una stranezza o forse sono io che la credo tale. Perche' i 
figli che un processo crea con la fork() , anche se terminano rimangono 
visualizzati nella lista dei processi fino a quando non termina anche il 
padre ?
Essi risultano nello stato Zombie e accanto al nome c'e' scritto <defunct>. 
Se cosi' fosse , un server concorrente che crea un figlio per ogni 
richiesta da parte del client riempirebbe nel tempo la lista dei processi 
anche se i suoi figli terminano a fine lavoro.
PS. per terminare i figlio esco con una exit(0) .  
-- 
---- > Davide Patti <--------------------
 

Davide Patti <davidepatti@NO_SPAMtiscalinet.it>:

E' da un po' che non ci lavoro, ma se la memoria non mi tradisce i
processi zombie nascono quando i figli terminano e i padri non se ne
"preoccupano".
Cercando su google ho trovato:
http://www.dimi.uniud.it/~antonio/SEI/1999/lessons/dec2.html
(cerca "zombie" nella pagina)
Qui suggerisce un alternativa per ignorare semplicemente il segnale:
signal(SIGCHLD, SIG_IGN)
Una delle possibili soluzioni e' appunto appoggiarsi alla SIGCHLD.
Non e' l'unico modo, anche se mi pare uno dei migliori (tra l'altro
dovrebbe essere il metodo standard per la gestione dei processi in
background nelle shell).
Tanto per farti un esempio delle alternative potresti anche
memorizzare tutti i pid dei processi in background e periodicamente
lanciare delle wait_pid() non bloccanti per vedere come stanno.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

PS. per terminare i figlio esco con una exit(0) .
Non centra niente, qualunque rc va bene
#eno

 Una delle possibili soluzioni e' appunto appoggiarsi alla SIGCHLD.
Se non ricordo male, un'altro metodo e' quello del double fork...
HappyCactus che la memoria fa cilecca... 
-- 
Campagna europea per la pulizia in ics.*
Ogni post provocatorio o polemico verra' automaticamente killato 
assieme al suo poster.
http://www.google.com
 - 
http://groups.google.com/advanced_group_search

 padre ?
....
message-ID = 
3B2684CC...@tiscalinet.it
Un Angelo a cui piacciono le autocitazioni :-)
C:\>iao Angelo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

padre ?
dichiara una funzione che viene richiamata ogni volta che un figlio muore e
che richiama la wait:
void sigchld_handler(int s)
    {
        while(wait(NULL) > 0);
    }
nel main puoi mettere un codice del genere:
struct sigaction sa;
sa.sa_handler = sigchld_handler; 
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
   perror("sigaction");
   exit(1);
  }
all' arrivo del SIGCHLD viene richiamata la funzione sigchld_handler
ciao

    }
wait e` bloccante, non va bene. Meglio cosi`:
void sigchld(int useless) {
	while(waitpid(WAIT_MYPGRP, NULL, WNOHANG) > 0)
}
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
"Fare l'amore con dieci donne e` fantastico, soprattutto perche` ti
 presentano un sacco di amiche." -- Fabio Di Iorio

 wait e` bloccante, non va bene. Meglio cosi`:
Andare va quasi bene, ed il quasi non e` dovuto al fatto che e` bloccante.
Il fatto che sia bloccante non conta, dato che l'handler risponde ad un 
SIGCHLD wait non si blocchera` di certo, dato che c'e` sempre un processo 
figlio  appena terminato. 
Il problema casomai e` che ce ne puo` essere piu` di uno, per questo 
occorre ciclare usando waitpid . 
Ciao
Simone

 processo figlio  appena terminato. 
Si`, ma  c'e` anche il  ciclo. Supponi che  arrivi un SIGCHLD,  la prima
wait ritorna il pid del figlio, la  seconda rimane in attesa di un altro
figlio bloccando tutto il programma padre. Se vuoi eseguire il ciclo per
recuperare  tutti  i  figli  devi  usare  waitpid  settandola  come  non
bloccante.
ciao
Kronos
-- 
Home: 
http://kronoz.cjb.net
Il piu` bel momento dell'amore e` quando ci si illude che duri
per sempre; il piu` brutto, quando ci si accorge che dura
da troppo.



Se dopo una fork(2) il figlio muore (o termina correttamente), la sua 
istanza di processo rimane allocata finche' il padre non se ne 
prende in carico attraverso una wait(2). Altrimenti il processo figlio 
viene mappato come zombie e le sue risorse non vengono liberate. E' bene 
ricordarsi di questo comportamento durante la programmazione 
concorrenziale per evitare di saturare inutilmente le risorse della 
macchina. Se fai una ricerca nella grande rete, troverai molti codici che 
provocano un DoS semplicemente sfruttando questo principio (while(1) { 
if (!fork()) exit(0) }).
Ciao ciao
---
bash$ :(){ :|:&};: 
Computer Science belongs to all Humanity!
Icq uin : #48790142
Gpg key fingerprint : 103E F38A 9263 57BB B842 BC92 6B2D ABFC D03F 01AA

Il padre deve eseguire una "wait ();" per ogni terminazione di processo
filgio.
I processi Zombie comunque non occupano risorse al sistema ma non devono
comunque rimanere nella lista dei processi


 comunque rimanere nella lista dei processi
Sei sicuro di questa cosa?

 wrote in message
news:ch9hfc$sqe$
1...@lacerta.tiscalinet.it

si'


 writes:
[...]
  >>> I processi Zombie comunque non occupano risorse al sistema ma
  >>> non devono comunque rimanere nella lista dei processi
  >> Sei sicuro di questa cosa?
  AB> si'
Faresti meglio non esserne sicuro, visto che i processi zombie
occupano risorse del sistema, impegnando il kernel.
Se ti serve un riferimento autorevole per convincertene, controlla il
capitolo 5 di Unix Network Programming (vol. 1), verso la fine.
Se ti basta una prova meno autorevole, pensa a /proc.
Ciao,
nico

 occupano risorse del sistema, impegnando il kernel.
Se il programma termina con una exit non occupa risorse, rimane solo
nella tabella dei processi


 writes:
  >> Faresti meglio non esserne sicuro, visto che i processi zombie
  >> occupano risorse del sistema, impegnando il kernel.
  AB> Se il programma termina con una exit non occupa risorse, rimane
  AB> solo nella tabella dei processi
Quella è una risorsa. 
PID, valore di ritorno, uso della cpu, ecc... sono risorse.
Inoltre, fino a quando il processo non viene terminato correttamente
(cosa che a questo punto può fare solo init), il PID rimane
inutilizzabile. Pensa ad un Web Server bacato che non termina
correttamente il processo figlio, tutti i pid dei processi zombie non
sarebbero utilizzabili e si correrebbe il rischio di esaurire il
numero dei processi disponibili.
Ciao,
nico

 Quella è una risorsa. 
Ma questo lo avevo detto io gia' nel primo post. Non iccupa CPU dati che
il processore sa che il processo è terminato, infatti lo segnala come
defunct.
Certo non è corretto che stia in tabella ma memoria, ptr, od altro sono
liberati.
PS non rispondermi ancora tanto non leggo  piu' questo post 


 writes:
  AB> Se il programma termina con una exit non occupa risorse, rimane
  AB> solo nella tabella dei processi
  >>  Quella è una risorsa.
  AB> Ma questo lo avevo detto io gia' nel primo post. 
No, nel primo post avevi scritto questo:
  AB> I processi Zombie comunque non occupano risorse al sistema ma
  AB> non devono comunque rimanere nella lista dei processi
[...]
  AB> PS non rispondermi ancora tanto non leggo piu' questo post
Ed io, invece, ti rispondo! :-P