Newsgroup: it.comp.os.linux.development
Titolo: uso di fork() in Linux

Ciao a tutti,
avrei bisogno di alcuni chiarimenti relativamente al funzionamento di
fork().
Spesso vedo che i sorgenti di esempio reperibili in rete presentano i
seguenti controlli dopo la chiamata a fork:
pid = fork();   //creazione del processo
if( pid > 0 )    //siamo sul padre
{...}
else    // pid <=0; siamo sul figlio o c'è errore
{...}
Mi chiedevo perchè sia necessario controllare quale processo è in
esecuzione.
E' aleatoria la questione per l'utente-programmatore.
Capisco bene che deve essere un concetto base della programmazione
multitasking, ma non sono molto esperto.
Vi ringrazio anticipatemente
-- 
scrubber
------------------------------------------------------------------------
scrubber's Profile: 
http://www.linuxforum.it/member.php?userid=607
View this thread: 
http://www.linuxforum.it/showthread.php?t=15635

 multitasking, ma non sono molto esperto.
La fork() crea un nuovo processo (figlio) e questo eredita l'ambiente 
di esecuzione del creatore (padre).  Il figlio eredita dal padre anche 
il punto di esecuzione, cioè l'uscita della fork().  La fork() ritorna 
al padre il PID del figlio ed il figlio riceve 0.  Generalmente viene 
creato un nuovo processo allo scopo di fare attività diverse da quelle 
del padre ed il test sul valore di ritorno serve per discriminare 
quale dei due processi è stato schedulato dal SO.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

grazie Giovanni.
Il mio dubbio è appunto sul come il S.O. schedula i processi che creo.
Se per esempio il processo genitore svolge delle attività che devono
essere eseguite prima di altre, con quei controlli sembra che io non so
se venga eseguito prima il padre del figlio.
Perciò: è corretto dire che non sono noti i criteri di schedulazione?
Thanks in advance


 Perciò: è corretto dire che non sono noti i criteri di schedulazione?
il criterio di schedulazione e' quello del kernel.
quando esegui fork() hai due processi indipendenti
scedulatiindipendentemente.
se devi far eseguire qualcosa "in ordine", ho esegui la fork() dopo o ti
serve qualche altro meccanismo di sincronizzazione tra processi.
ilSimo
-- 
now playing: Neon Genesis Evangelion - Cruel Angel Thesis
Marble walls are painted red, oh don't give our home free
See our wives and children cry, don't dive into defeat
                                Drakkar - The Walls Of Olathoe

 Perciň: č corretto dire che non sono noti i criteri di schedulazione?
I criteri sono noti in modo DETERMINISTICO.

Ora mi è tutto chiaro!
Se la chiamata a fork() è eseguita con successo, il figlio creato è la
copia del padre, ma "in parallelo". Quindi ha una copia dei segmenti di
testo, stack e dati del padre al momento dell'invocazione della fork().
Come conseguenza, il codice eseguito dal figlio è esattamente lo stesso
del padre; quindi quegli "if" di controllo ecco che hanno senso.
Che gran cosa scoprire di non sapere ed imparare quello che non si
sapeva!
Saluti a tutti


 
Quoto.
Considera com.que che su linux il child viene fatto "partire" prima del 
padre (da che ver. del kernel non ricordo). Questo per ottimizzare, dato 
che subito dopo la fork le pagine sono condivise tra parent e child (viene 
implementata politica di copy on write), si vuole evitare che nel caso che 
il child chiami subito un' exec* - come accade abbastanza di frequente -  
di dover ri-inizializzare una regione che e' stata appena duplicata da 
quella del parent. (spero sia chiaro...:)
Bye

 Perciò: è corretto dire che non sono noti i criteri di schedulazione?
esegui le operazioni prima di forkare. Tutto il resto è una speculazione 
che porta di sicuro ad accrocchioni buggati :-)

 che porta di sicuro ad accrocchioni buggati :-)
Più che altro ci sono librerie apposite per queste cose, a farlo a mano 
si fa più fatica e si rischia di sbagliare. Unica eccezione: devi farlo 
come esercizio per un esame.
-- 
Lorenzo `paulatz' Paulatto
Trieste
``Grandissima mi par l'inezia di coloro che vorrebbero che Iddio avesse 
fatto l'universo più proporzionato alla piccola capacità del lor discorso.''
      --Galileo Galilei (Opere VII)

 come esercizio per un esame.
imho se c'è un corso in cui ti insegnano a fare accrocchioni vari per 
sapere cosa schedulerà il kernel dopo un fork da userspace è meglio 
cambiare ateneo.

 meglio cambiare ateneo.
Non ci sono accrocchi da fare per garantire che un processo padre o 
figlio venga schedulato prima o dopo dell'altro.  Una sleep() od 
usleep() posta immediatamente dopo la fork() nel ramo padre (o figlio) 
garantisce la schedulazione dell'altro processo.


 garantisce la schedulazione dell'altro processo.
Calma... "Garantisce" è una parola grosssa... rende più probabile mi va
bene... ma garantire neanche per sogno. 
Ciao,
-- 
 Daniele Orlandi                                                        つづく

 Giovanni
falso:
The sleep() function suspends execution of the calling thread until 
either seconds seconds have elapsed or a signal is delivered to the 
thread and its action is to invoke a signal-catching function or to 
terminate the thread or process. System activity may lengthen the sleep 
by an indeterminate amount.

 mi va bene... ma garantire neanche per sogno.
Se non ci sono pasticci con le priorità e viene usato uno scheduler di 
processi round-robin una sleep() di un secondo lascia ampi margini 
perché ci sia la (quasi) garanzia che chi non va in attesa venga 
schedulato prima dell'altro.  Questo secondo la mia esperienza.
Rimangono naturalmente fuori casi particolari in cui lo scheduler non 
è quello standard e sono state cambiate le priorità dei processi.


 the sleep by an indeterminate amount.
Anche a te rispondo come a Daniele Orlandi.  Stai citando casi 
particolari.
Se non ci sono pasticci con le priorità e viene usato uno scheduler di 
processi round-robin una sleep() di un secondo lascia ampi margini 
perché ci sia la (quasi) garanzia che chi non va in attesa venga 
schedulato prima dell'altro.  Questo secondo la mia esperienza.
Ciao


 schedulato prima dell'altro.  Questo secondo la mia esperienza.
Una quasi garanzia non e` una garanzia, ma rimane una possibilita`.
Lo scheduling e` un processo troppo complesso per avere garanzie 
semplicemente con un'attesa. Il kernel potrebbe essere bloccato in un I/O 
e rischedulare lo stesso processo padre prima del figlio. La sleep() 
potrebbe addirittura alzargli la priorita` perche` sembra un processo 
poco pesante.
L'unico modo per essere sicuri e` usando una wait() sul figlio e mandando 
un opportuno segnale dal padre dopo che ha fatto quello che deve fare.
Bye.

 particolari.
Quando fai programmazione concorrente devi presupporre che i casi
particolari si verifichino SEMPRE.
Perché quando si verifica il caso particolare cosa succede? Crasha il
programma? Fa cose ben peggiori? E se il programma è "mission critical"[1]? 
Ciao,
[1]Qualunque cosa voglia dire "mission critical"
-- 
 Daniele Orlandi                                                        つづく

 schedulato prima dell'altro.  Questo secondo la mia esperienza.
1) "(quasi) garanzia" non vuol dire nulla. O garantisci il 100% o non 
garantisci. E non puoi garantire che non ti arrivi un segnale che svegli 
il task. E' vero: è un caso raro, ma esiste.
2) ragioni facendo troppe ipotesi sullo scheduler, che in verità non 
puoi sempre verificare.
Meglio investire il tempo nel design del software che nelle speculazioni 
sulla schedulazione.

 [1]Qualunque cosa voglia dire "mission critical"
afaik : che cade l'aereo sul quale gira :)

 afaik : che cade l'aereo sul quale gira :)
Tu ci scherzi... ma se sapessi quanti casini causa l'elettronica di bordo in
aerei grandi e piccoli....
Ecco perché volo in aliante :)


 afaik : che cade l'aereo sul quale gira :)
m'ero sbagliato, a parte che non è "mission" qualcosa ,ma "failure"
qualcosa
quando l'aereo cade è failure catastrophic!
http://en.wikipedia.org/wiki/Catastrophic_failure