1 / 41

Creazione e terminazione dei processi

Creazione e terminazione dei processi. Tommaso Motta www.webalice.it/motta.tommaso. Introduzione. Sistema multitasking : più processi in esecuzione in contemporanea ho parallelismo reale solo se c’è un processore per ogni processo, altrimenti i processi avanzano alternati (time-sharing)

Download Presentation

Creazione e terminazione dei processi

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Creazione e terminazione dei processi Tommaso Motta www.webalice.it/motta.tommaso Generazione e terminazione processi

  2. Introduzione • Sistema multitasking:più processi in esecuzione in contemporanea • ho parallelismo reale solo se c’è un processore per ogni processo, altrimenti i processi avanzano alternati (time-sharing) • 2 tipologie di processi • processi di sistema operativo: realizzano servizi e gestiscono le risorse del sistema • processi utente: sono mandati in esecuzione dall’utente Generazione e terminazione processi

  3. Processi permanenti e temporanei • I processi possono essere: • permanenti: vengono creati all’avvio del sistema operativo e continuano fino alla chiusura del s.o. • temporanei: vengono creati quando servono e poi terminano • necessitano di meccanismi per la generazione e la terminazione dei processi Generazione e terminazione processi

  4. Generazione dei processi • I processi temporanei possono essere generati da • altri processi (permanenti o temporanei) • o dalla richiesta di un nuovo processo da parte di un utente interattivo (ad. es.: attivazione di un’icona) • Ogni creazione di un processo corrisponde ad una chiamata di sistema (system call) • Quando un processo richiede la generazione di un processo (processo figlio) deve indicare il programma (codice) da associare al processo che viene generato Generazione e terminazione processi

  5. Generazione dei processi • Dopo la generazione del processo il padre può: • sospendersi in attesa che il figlio termini... oppure... • ...continuare ad evolversi in concorrenza con il figlio • Un processo può suddividersi in un numero n di attività che avanzano parallelamente Generazione e terminazione processi

  6. Attività per la generazione di un processo • Per generare un processo il S.O. deve: • verificare la disponibilità di spazio in memoria RAM per il processo e per il suo PCB • se non è disponibile la memoria bisogna fare swapping (memoria virtuale) • assegnare la memoria al processo • creare il PCB Generazione e terminazione processi

  7. Terminazione di processi • I processi temporanei possono • terminare spontaneamente (normale conclusione o condizioni di errori) • terminare involontariamente (errori “fatali” o fatti terminare da altri processi o da un utente) Generazione e terminazione processi

  8. Terminazione dei processi • In un sistema sono necessari • meccanismi di terminazione utilizzabili dal processo che intende terminare • meccanismi di soppressione con il quale un processo può causare la terminazione di un altro processo temporaneo • i meccanismi di soppressione possono essere invocati solo da: • processi antenati (padre) o processi permanenti • utente che ha mandato in esecuzione il processo o amministratore Generazione e terminazione processi

  9. Terminazione dei processi • Quando un processo termina invia al processo padre un segnale • Alla terminazione o soppressione di un processo è necessario: • verificare la legittimità dell’operazione (l’utente/processo può sopprimere questo processo?) • rilasciare la memoria e tutte le risorse del processo • notificare la terminazione al processo padre (se non è già terminato prima...) Generazione e terminazione processi

  10. Windows: API per generazione e terminazione di processi • Windows NON ha il concetto di gerarchia di processi • API utili per creare e terminare i processi: • CreateProcess(): crea un processo • CreateThread(): crea un thread in un processo esistente • ExitThread(): termina il thread corrente • ExitProcess(): termina il processo e tutti i suoi threa • TerminateProcess(): permette a un processo di far terminare un altro processo Generazione e terminazione processi

  11. Creazione e terminazione processi in Linux Tommaso Motta www.webalice.it/motta.tommaso Generazione e terminazione processi

  12. Gerarchia di processi • Ogni processo deriva dalla duplicazione di un processo esistente • l’unico processo che non deriva da duplicazione è il processo iniziale (init) • Un processo permanente o temporaneo può generare processi figli temporanei • Tutti i processi sono legati in una struttura ad ALBERO • Il comando pstree mostra i processi eidenziando la struttura gerarchica Generazione e terminazione processi

  13. Gerarchia di processi Generazione e terminazione processi

  14. Creazione di processi: fork • Il comando fork indica che in quel punto deve essere attivato un nuovo processo • I due processi evolvono indipendentemente • l’esecuzione viene suddivisa in due esecuzioni distinte • Il comando crea un processo figlio che è la COPIA ESATTA del processo padre • al padre viene restituito il PID del figlio (valore negativo se non ha funzionato) • al figlio viene restituito il valore 0 Generazione e terminazione processi

  15. Fork ( ) • I due processi hanno descrittori (PCB) e immaginidistinte • Il processo figlio eredita da padre il programma e l’immagine nel processore • Dopo la generazione i due processi avanzano indipendentemente eseguendo lo stesso programma Generazione e terminazione processi

  16. Fork e S.O. • Quando si usa la fork il S.O. deve: • allocare un nuovo PCB e inserirlo nella tabella dei processi • assegnare al processo un PID • fare una copia logica di tutti i dati del processo padre • in realtà molte aree di memoria rimangono condivise, vengono duplicate solo le aree su cui uno dei due fa una modifica • restituire il PID del figlio al padre e 0 al figlio • collocare il nuovo processo nella lista dei processi pronti Generazione e terminazione processi

  17. Creazione: fork() pid_t fork(void); • crea un nuovo processo con indice pid • lo spazio di indirizzamento del nuovo processo è un duplicato di quello del padre • restituisce 0 al figlio e pid al padre • oppure -1 (solo al padre) in caso di fallimento • es. la tabella dei processi non ha più spazio ... Generazione e terminazione processi

  18. Terminazione dei processi • Un processo termina eseguendo la chiamata di sistema exit che • libera tutte le risorse • “ripudia” i figli => diventano di proprietà di init e quando muoiono vengono da lui eliminati • Il processo che esegue la exit diventa uno zombie • i processi genitori devono eliminare gli zombie • un processo può sopprimere un altro processo con la chiamata di sitema kill Generazione e terminazione processi

  19. Terminazione: exit() void exit(int status); • il codice di terminazione della exit (cioè l’intero passato come parametro) viene “restituito" al padre. • Se il processo che termina non ha più un processo padre (è già terminato) il valore viene restituito all’interprete comandi del S.O. • chiude tutti i descrittori di file, • libera lo spazio di indirizzamento, • invia un segnale SIGCHLD al padre • se il processo padre è terminato, il processo ‘orfano’ viene adottato da init (cioè il ppid viene settato a 1) Generazione e terminazione processi

  20. Esempio creazione di processi /* frammento che crea un nuovo processo */ int pid; /* pid del processo creato */ pid = fork(); if ( pid == 0 ) { /* siamo nel figlio */ printf(“Processo figlio”); exit(1); } else { /* siamo nel padre */ printf(“Processo padre”); exit(1); } Generazione e terminazione processi

  21. PID del processo: getpid() • La funzione getpid • consente ad un processo di conoscere il valore del proprio pid • Prototipo getpid: pid_t getpid(void) • il kernel ha pid 0 • init ha pid 1 Generazione e terminazione processi

  22. PID del padre: getppid() • La funzione getppid • consente ad un processo di conoscere il valore del pid del processo padre • Prototipo getppid: pid_t getppid(void) Generazione e terminazione processi

  23. Esempio 1 #include <stdio.h> #include <sys/types.h> void main(int argc, char * argv[]) { pid_t pid; int retstatus=0; pid = fork(); if (pid==0) /* sono nel figlio*/ {printf (“sono il processo figlio\n”); retstatus=1; exit(retstatus);} else /* pid != 0, sono nel padre */ {printf (“sono il processo padre\n”); exit(retstatus);} } Generazione e terminazione processi

  24. Esempio 2: getpid #include <stdio.h> #include <sys/types.h> void main() { pid_t pid; printf (“Prima della fork: PID = %d\n”, getpid()); pid = fork(); if (pid==0) /* PROCESSO FIGLIO*/ {printf (“FIGLIO: PID = %d\n”, getpid()); exit(0);} else /* PROCESSO PADRE */ {printf (“PADRE: PID = %d\n”, getpid()); printf (“PADRE: PID DEL FIGLIO = %d\n”, pid); exit(0);} } Generazione e terminazione processi

  25. Esempio 2: esecuzione getpid Prima della fork: PID = 3375 FIGLIO: PID = 3399 PADRE: PID = 3375 PADRE: PID DEL FIGLIO = 3399 • Dal risultato dell’esecuzione si deduce che l’ordine di esecuzione dei processi è stato: figlio e padre • Nota bene: quando la fork è stata eseguita, è stato creato il secondo processo e l’esecuzione può proseguire o con il processo padre per primo oppure con il processo figlio per primo Generazione e terminazione processi

  26. Esempio 3: generazione di 2 figli void main() { pid_t pid1, pid2; pid1 = fork(); if (pid1==0) /* PRIMO PROCESSO FIGLIO*/ {printf (“FIGLIO 1: PID = %d\n”, getpid()); printf (“FIGLIO 1: eseguo exit\n”); exit(0);} else /* PROCESSO PADRE */ {pid2 = fork(); if (pid2==0) /* SECONDO PROCESSO FIGLIO*/ {printf (“FIGLIO 2: PID = %d\n”, getpid()); printf (“FIGLIO 2: eseguo exit\n”); exit(0);} else /* PROCESSO PADRE */ {printf (“PADRE: PID = %d\n”, getpid()); printf (“PADRE: PID DEL FIGLIO 1 = %d\n”, pid1); printf (“PADRE: PID DEL FIGLIO 2 = %d\n”, pid2); exit(0); } } Generazione e terminazione processi

  27. Esempio 3: esecuzione • Nell’ipotesi che l’ordine di esecuzione sia • figlio1, padre, figlio2, padre FIGLIO 1: PID = 4300 FIGLIO 1: eseguo exit FIGLIO 2: PID = 4335 FIGLIO 2: eseguo exit PADRE: PID = 3375 PADRE: PID DEL FIGLIO 1 = 4300 PADRE: PID DEL FIGLIO 2 = 4335 Generazione e terminazione processi

  28. Esempio 4: ancora 2 figli... void main() { pid_t pid; pid = fork(); if (pid==0) /* PRIMO PROCESSO FIGLIO*/ {printf (“(1)sono il primo figlio con pid: = %d\n”,getpid()); exit(0);} else /* PROCESSO PADRE */ {printf (“(2)sono il processo padre\n”); printf (“(3)ho creato un primo figlio con pid: = %d\n”,pid); printf (“(4)il mio pid e’: = %d\n”,getpid()); pid = fork(); if (pid==0) /* SECONDO PROCESSO FIGLIO*/ {printf (“(5)sono il secondo figlio con pid: = %d\n”,getpid()); exit(0);} else /* PROCESSO PADRE */ {printf (“(6)sono il processo padre\n”); printf (“(7)ho creato un secondo figlio con pid: =%d\n”,pid); exit(0);} } } Generazione e terminazione processi

  29. Esempio 4: esecuzione 2)sono il processo padre 1)sono il primo figlio con pid: = 695 3)ho creato un primo figlio con pid: = 695 4)il mio pid e’: = 694 6)sono il processo padre 5)sono il secondo figlio con pid: = 696 7)ho creato un secondo figlio con pid: 696 Generazione e terminazione processi

  30. Attesa di terminazione del figlio • Il processo padre, dopo aver generato il figlio può sospendersi in attesa della sua terminazione: • invoca la chiamata di sistema wait che sincronizza il padre con l’evento relativo alla terminazione del figlio • La wait permette di riunificare due o più processi concorrenti in un unico processo • Il processo che chiama la wait rimane bloccato fino a quando non è terminato il processo figlio Generazione e terminazione processi

  31. Attesa terminazione figlio: wait • La funzione wait • sospende l’esecuzione del processo padre che la esegue ed attende la terminazione di un qualsiasi processo figlio; • se il figlio termina prima che il padre esegua la wait, l’esecuzione della wait nel padre termina istantaneamente. • Prototipo wait: pid_t wait (int*) • il valore restituito dalla funzione (di tipo pid_t) è il valore del pid del figlio terminato. • il parametro passato per indirizzo assume il valore del codice di terminazione del figlio (e cioè il valore del parametro della exit eseguita dal figlio per terminare). Generazione e terminazione processi

  32. Esempio: wait #include . . . . void main(int argc, char * argv[]) { pid_t pid; int stato_exit, stato_wait; pid = fork(); if (pid==0) {printf (“sono il processo figlio\n”); printf(“il mio pid e’: %d \n”,getpid( )); stato_exit=5; exit(stato_exit);} else {printf("Ho generato il processo figlio con pid %d\n",pid) pid = wait(&stato_wait); printf("E’ terminato il processo %d con esito %d\n",pid, stato_wait/256);} } Generazione e terminazione processi

  33. Attesa terminazione figlio: waitpid • La funzione waitpid • Sospende l’esecuzione del processo padre ed attende la terminazione del processo figlio di cui vienefornito il pid; • se il figlio termina prima che il padre esegua la waitpid, l’esecuzione della waitpid nel padre termina istantaneamente. • Prototipo waitpid pid_t waitpid(pid_t pid, int *status, int options); • nel padre: • il valore resitituito assume il valore del pid del figlio terminato; • status assume il valore del codice di terminazione del processo figlio; • options specifica ulteriori opzioni (ipotizziamo > 0). Generazione e terminazione processi

  34. Esempio: waitpid #include . . . void main(int argc, char * argv[]) { pid_t pid, my_pid; int status; pid = fork(); if (pid==0) {/* CODICE DEL FIGLIO */ } else /* pid != 0, sono nel padre */ {printf ("Ho generato il processo figlio con pid %d\n",pid); printf("Attendo la terminazione del figlio con pid %d\n",pid); my_pid = waitpid(pid, &status, 1); printf("E’ terminato il processo %d con esito %d\n",my_pid, status);} } Generazione e terminazione processi

  35. Sostituzione del programma in esecuzione: exec • La funzione exec • sostituisce il segmento codice e il segmento datidel processo corrente con il codice e i dati di un programma contenuto in un file eseguibile specificato. • Il segmento di sistema non viene sostituito (file e socket rimangono aperti e disponibili) • il processo rimane lo stessoe quindi mantiene lo stesso pid • la funzione exec passa dei parametri al programma che viene eseguito, tramite il meccanismo di passaggio dei parametri al main argc e argv Generazione e terminazione processi

  36. Sintassi exec • Sintassi: int execl(char *path_programma, char *arg0, char *arg1,..char *argn); • path_programma: path completo del file eseguibile del nuovo programma da lanciare • arg0,arg1, … argn: puntatori a stringhe che verranno passate come parametri al main del nuovo programma • arg0 deve essere il nome del programma • argn in chiamata deve essere il valore NULL • il valore restituito è: • 0 se l’operazione è stata eseguita correttamente; • -1 se c’è stato un errore e l’operazione di sostituzione del codice è fallita. • Al momento dell’esecuzione del main del nuovo programma - void main (int argc, char *argv[]) - arg0, arg1 .. vengono resi accessibili tramite l’array di puntatori argv Generazione e terminazione processi

  37. Esempio: exec /* programma main1 */ #include <stdio.h> void main(int argc, char * argv[]) {int i; printf (“programma main1 in esecuzione\n”); printf (“ho ricevuto %d parametri\n”, argc); for (i=0; i<argc; i++) printf(“il parametro %d e’: %s \n”,argv[i]); } /* programma exec1 */ #include <stdio.h> #include <sys/types.h> void main(int argc, char * argv[]) {char PO[]=“main1”; char P1[]=“parametro1”; char P2[]=“parametro2”; printf (“programma exec1 in esecuzione\n”); execl(“/antola/esempi/main1”,P0,P1,P2,NULL); printf (“errore di exec”); } Generazione e terminazione processi

  38. Esempio: esecuzione Eseguo il programma exec1: programma exec1 in esecuzione programma main1 in esecuzione ho ricevuto 3 parametri il parametro 0 e’:main1 il parametro 1 e’:parametro1 il parametro 2 e’:parametro2 Generazione e terminazione processi

  39. Utilizzo fork-exec • La sostituzione di codice non implica necessariamente la generazione di un figlio • in questo caso, quando il programma che è stato lanciato in esecuzione tramite la execl termina, termina anche il processo che lo ha lanciato (sono lo stesso processo!!) • E’ necessario creare un nuovo processo, che effettua la sostituzione di codice (utilizzo di fork- exec), quando è necessario “mantenere in vita” il processo di partenza, dopo l’esecuzione del codice sostituito • spesso questo implica che il padre attenda la terminazione del programma lanciato con mutazione di codice Generazione e terminazione processi

  40. Esempio: fork-exec void main() { pid_t pid, chpid; pid = fork(); if (pid==0) /* PROCESSO FIGLIO*/ {printf (“FIGLIO: prima del cambio di codiced\n”) printf (“FIGLIO: PID = %d\n”, getpid()); execl(“./prog”, “prog”, NULL); printf (“FIGLIO: errore nel cambio di codice\n”); exit(1);} else /* PROCESSO PADRE */ {printf (“PADRE: wait\n”); chpid = wait (NULL); printf (“PADRE: PID DEL FIGLIO = %d\n”, chpid); exit(0); } } Generazione e terminazione processi

  41. Esempio: fork-exec (...continuo) /* Programma prog*/ void main (int argc, char * argv[]) { printf (“PROG: PID = %d\n”, getpid()); printf (“PROG: exit\n”); } • ESECUZIONE nell’ipotesi che venga eseguito prima il padre e poi il figlio PADRE: wait FIGLIO: prima del cambio del codice FIGLIO: PID = 4995 PROG: PID = 4995 PROG: exit PADRE: PID DEL FIGLIO = 4995 Generazione e terminazione processi

More Related