PDA

View Full Version : [c]Creare processi con la fork


anx721
20-04-2004, 17:19
Salve, ho un problema a far funzionare la fork per creare dei processi. Il mio scopo è avere il processo padre che crea 2 processi figli ognuno dei quali stampa una stringa. Ho scritto questo codice, in cui in un ciclo for il padre esegue la fork creando un figlio ad
ogni iterazione:


#include <unistd.h>
# include <stdio.h>

int main( int argc, char **argv)
{
printf("\nInizio");

int pid = 1;
int testNumber;

for(testNumber = 0; ((testNumber < 2) && (pid != 0)); testNumber++){
pid = fork();
}

//Se sono il figlio pid vale zero e quindi stampo
if(pid == 0){
if(testNumber == 1){
printf("\nuno");
}
if(testNumber == 2){
printf("\ndue");
}
}

return 0;
}


Io mi aspetterei di vedere stampate in qualche ordine le stringhe "Inizio" "uno" "due",

ivece ottengo:

Inizio Inizio Inizio uno due in qualche oridne.

Come mai? Non riesco a capire questo output. Perche Inizio appare tre volte? :mc:

ilsensine
20-04-2004, 17:36
Non hai fatto nessun errore, ma è...giusto così :D
Ti do un indizio: se sostituisci printf(..) con fprintf(stderr, ...) hai l'output desiderato ;)

anx721
20-04-2004, 17:57
Ma perche bisogna fare cosi? Perche stampa 3 volte Inizio?

ilsensine
20-04-2004, 20:38
La printf scrive su stdout, che è line-buffered. Ciò vuol dire che i caratteri vengono mantenuti in un buffer interno, fino a quando una riga è completa (il fine riga è il carattere '\n'). Avrai fatto caso, forse, che "inizio" viene stampato 3 volte, ma il '\n' prima di "inizio" viene stampato una sola volta.
Quindi, in soldoni: nel momento in cui fai il fork, sia il processo padre che il processo figlio ricevono una copia esatta di tutte le variabili, compreso il buffer di stdout e ciò che si trova dentro. Entrambi i processi, dunque, si ritrovano "Inizio" nella coda per stdout. Questo spiega il comportamento apparentemente assurdo.

cionci
20-04-2004, 21:13
Attenzione che non è garantito che ti stampi "Inizio uno due"...ma può stampare anche "Inizio due uno"...

anx721
20-04-2004, 22:24
Originariamente inviato da cionci
Attenzione che non è garantito che ti stampi "Inizio uno due"...ma può stampare anche "Inizio due uno"...

Si questo lo prevedevo.

Grazie sensine, ora ho capito quello che avviene, in effetti non capivo neanche perche gli accapo un po' c'erano e un po no :p

anx721
21-04-2004, 13:11
Visto che mi trovo, come si fa a sincronizzare i processi?
In particolare io vorrei che il processo padre non termini prima dei fili. Ho uilizzato subito dopo la fork l'istruzione

wait(...)

che mette in attesa un processo finche non è terminato uno dei figli, quindi il padre dovrebe attendere la terminazione dell'unico figlio generato nel ciclo for prima di andare avanti generando un altro figlio. Pero quello che accade è che il padre termina comunque prima. Come dovrei fare allora per realizzare quello che voglio?

cn73
21-04-2004, 13:41
La sincronizzazione dei processi è un argomento molto vasto e complesso. Nel tuo specifico caso ecco un esempio:


/* USO DELLA FORK CON WAIT: fork-wait.c */

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>

main()
{
int i,n,w;
n = fork();
if (n == -1)
{
fprintf(stderr,"fork fallita\n");
exit(1);
}
else
if ( n == 0) /* processo figlio */
{
printf("\n(figlio) il mio process-id e` %d\n",getpid());
printf("\n(figlio) ora aspetto 5 secondi\n");
for (i=0; i<5; i++)
{
system("sleep 1");
printf(".\n");
}
printf("(figlio) ho finito e muoio\n");
exit(0);
}
else /* processo padre */
{
printf("\n(padre) il mio process-id e` %d\n",getpid());
printf("\n(padre) ora aspetto il figlio\n");
w = wait(0);
printf("\n(padre) sono uscito dalla wait muoio anch'io\n");
exit(0);
}
}

cn73
21-04-2004, 13:45
Ti consiglio di approndire i discorsi sulla wait e sulle altre system call (signal, kill,exec) oltre che sui semafori, la memoria condivisa e le code di messaggi cercando in rete. Un ottimo link per la gestione dei processi link è http://www.lilik.it/~mirko/gapil/gapilch4.html#x69-450003