|
Iniziamo la trattazione del sistema operativo con la gestione dei processi.
Il testo dell'esercizio è il seguente:
Scrivere un programma in C che generi dieci processi
ed attenda il loro termine.
Per ogni processo che termina stamperà il codice di terminazione.
Ogni processo generato, che svolge il compito del processo figlio sarà numerato da
1 a 10.
Dopo una breve attesa (circa 50 ms) ogni figlio stamperà un
messaggio di presentazione, contenete l'indice del figlio. Dopo altri 500 mS
terminerà dando come codice di terminazione 100 + l'indice dell'istanza.
NOTE:
- Per generare processi in Linux si usa la funzione int fork ().
Questa funzione genera un nuovo processo come copia del processo corrente.
Il nuovo processo avrà una copia esatta delle variabili del processo originale e
l'esecuzione di questo nuovo processo comincerà dal punto immediatamente successivo
alla funzione fork ().
Per distinguere il processo che ha richiamato la fork (chiamato in genere padre) da quello prodotto ex novo dalla funzione stessa (chiamato figlio), si deve analizzare il valore di ritorno della funzione stessa:
- Un valore minore di zero (-1)
- Siamo nel processo padre, nessun figlio è stato creato (errore).
- Zero
- Siamo nel figlio.
- Un valore maggiore di zero
- Siamo nel padre. Il numero ritornato è il Process Identifyer (PID)
del processo figlio generato.
- Per fare un ritardo breve in maniera semplice possiamo usare la funzione
usleep (int microsecondi);. Come parametro indicheremo il numero di
microsecondi di ritardo che vogliamo fare.
- Per attendere la terminazione di un figlio, si può utilizzare la
funzione wait (int *status);. Nella variabile intera status, il cui
indirizzo verrà passato alla funzione, verranno insrite una serie di
informazioni su come il programma è stato terminato.
Per conoscere il codice di terminazione potremo usare la macro
WEXITSTATUS(status).
Una possibile soluzione è la seguente:
/* fork.c
* Stefano Salvi - 12/9/02
* programma genera 10 processi figli successivamente ogni
* figlio stampa il suo nome a distanza di un secondo l'uno dall'altro.
* Poi i figli ritornano 100 + n°figlio e il pgm stampa
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define NUMP 10 /* Numero di figli da generare */
int main()
{
int i,pid;
// Genera i 10 processi
for(i=0;i<NUMP;i++)
{
if((pid=fork())==0)
{ // pid=0 -> figlio
usleep(50000*(1+i)); // Ritardo iniziale
printf("Figlio: %d\n",i+1); // Stampa messaggio del figlio
usleep(500000*(1+i)); // Ritardo finale
return(101+i); // Termina con codice di ritorno
} else { // pid <> 0 -> padre (il pid e' quello del figlio)
printf("Ho generato il figlio %d con pid %d\n",i+1,pid);
}
}
// Attende che dieci processi terminino
for(i=0;i<NUMP;i++)
{
int status;
wait(&status); // Attende termine di un figlio (uno qualunque)
printf("Terminato processo %d\n",WEXITSTATUS(status));
}
}
|
Per provare il programma, scaricare il sorgente, compilarlo
con il comando cc fork.c ed eseguirlo con il comando ./a.out.
[Home Page dell'ITIS "Fermi"]
[Indice Quarta]
[Precedente]
[Successivo]
© Ing. Stefano Salvi - Released under GPL licence
|