T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

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

Transcript of T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

Page 1: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta Generazione e terminazione processi

1

Creazione e terminazione dei processi

Tommaso Motta

www.webalice.it/motta.tommaso

Page 2: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 3: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 4: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 5: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 6: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 7: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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)

Page 8: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 9: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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...)

Page 10: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 11: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta Generazione e terminazione processi

11

Creazione e terminazione processi in Linux

Tommaso Motta

www.webalice.it/motta.tommaso

Page 12: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 13: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta Generazione e terminazione processi

13

Gerarchia di processi

Page 14: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 15: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta Generazione e terminazione processi

15

Fork ( )

I due processi hanno descrittori (PCB) e immagini distinte

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

Page 16: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 17: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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 ...

Page 18: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 19: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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)

Page 20: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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);

}

Page 21: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 22: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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)

Page 23: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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);}

}

Page 24: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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);}

}

Page 25: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 26: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta Generazione e terminazione processi

26

Esempio 3: generazione di 2 figlivoid 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); }

}

Page 27: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 28: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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);}

}

}

Page 29: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 30: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 31: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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).

Page 32: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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);}

}

Page 33: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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 viene fornito 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).

Page 34: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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);}

}

Page 35: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta Generazione e terminazione processi

35

Sostituzione del programma in esecuzione: exec

La funzione exec

sostituisce il segmento codice e il segmento dati del 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 stesso e 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

Page 36: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 37: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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”);

}

Page 38: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 39: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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

Page 40: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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); }

}

Page 41: T. MottaGenerazione e terminazione processi1 Creazione e terminazione dei processi Tommaso Motta .

T. Motta 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