37
1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

Embed Size (px)

Citation preview

Page 1: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

1

SC che operano su processi

Getpid, fork, exec, wait, waitpid, exit, dup, dup2

Page 2: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

2

Process identifier: getpid,getppid– pid indice del processo all’interno della tabella dei processi– ppid indice del processo padre all’interno della tabella dei processi– il kernel ha pid 0 e init ha pid 1– si possono ottenere con

pid_t getpid(void)

pid_t getppid(void)

Page 3: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

3

PID: getpid,getppid (2)/* frammento che stampa il pid del processo in esecuzione e quello del padre usando la macro WRITE di stampa (in sysmacro.h) … */

char buf[N]; /* stringa da stampare */

sprintf(buf,”Processo %d, mio padre e’ %d\n.”, getpid(),getppid());

WRITELN(buf); …

Page 4: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

4

PID: getpid,getppid (2.1)/* da sysmacro.h … */

#define STIN 0

#define STDOUT 1

#define STDERR 2

#define WRITE(m) \ IFERROR(write(STDOUT,m,strlen(m)),m)

#define WRITELN(m) WRITE(m); WRITE(m);

Page 5: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

5

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

– padre e figlio hanno due tabelle dei descrittori di file diverse (il figlio ha una copia di quella del padre)

– MA …. condividono la tabella dei file aperti (e quindi anche il puntatore alla locazione corrente di ogni file)

Page 6: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

6

Creazione : fork() (2) pid_t fork(void);– 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 7: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

7

Text

Data

Stack

Area vuota

0

232 - 1

heap

Creazione di processi (2)• Spazio di indirizzamento di padre e figlio dopo

una fork terminata con successo

SI padre

Text

Data

Stack

Area vuota

0

232 - 1

heap

SI figlio

copia

Page 8: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

8

Text

Data

Stack

Area vuota

0

232 - 1

heap

Creazione di processi (3)• Come prosegue l’esecuzione nei processi padre e

figlio

SI padre (pid=34)

Text

Data

Stack

Area vuota

0

232 - 1

heap

SI figlio (pid = 45)

0&x&x 45

PC = istruzionesuccessiva a fork

Page 9: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

9

Creazione di processi (4)/* frammento che crea un nuovo processo */

int pid; /* pid del processo creato */

IFERROR( pid = fork(),”main: creazione”);

if ( pid ) { /* siamo nel padre */

sprintf(buf,”Processo %d, ho creato %d\n.”,

getpid(),pid);

WRITELN(buf); }

else { /* siamo nel figlio */

sprintf(buf,”Processo %d, mio padre e’ %d\n.”,

getpid(),getppid());

WRITELN(buf);

}

Page 10: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

10

Terminazione : exit() void exit(int status);– chiude tutti i descrittori di file,– libera lo spazio di indirizzamento,– invia un segnale SIGCHLD al padre– salva il primo byte (0-255) di status nella tabella dei processi in attesa che il padre lo accetti (con la wait(), waitpid())– se il processo padre è terminato, il processo ‘orfano’ viene adottato da init (cioè ppid viene settato a 1) – se eseguita nel main è equivalente ad una return

Page 11: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

11

Attesa di terminazione del figliopid_t wait(int *status)

pid_t waitpid(pid_t pid,int *status,int options)– restituisce informazioni sul tipo di terminazione del figlio e il byte meno significativo ritornato con la exit()

• per leggere queste informazioni c’è bisogno di opportune maschereWIFEXITED(status)

WEXITSTATUS(status)

– in caso di errore (es non ci sono figli …) viene ritornato il valore -1

Page 12: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

12

Attesa di terminazione ...(2)pid_t wait(int *status)

pid_t waitpid(pid_t pid,int *status,int options)– la waitpid permette di fare attese non bloccanti

• WNOHANG specificato nelle opzioni indica di non attendere se nessun figlio è ancora terminato

– permette di attendere un figlio con un pid specifico (pid)

Page 13: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

13

Esempio : wait() ed exit() int status ; /* conterra’ lo stato */

IFERROR( pid = fork(),”main: creazione”);

if ( pid ) { /* siamo nel padre */

sleep(20); /* aspetta 10 secondi */

pid = wait(&status);

if (WIFEXITED(status)) {

/*!=0 se il figlio e’terminato normalmente, (exit o return) non ucciso da signal */

printf(“stato %d\n”, WEXITSTATUS(status));

}

else { /* siamo nel figlio */

printf(“Processo %d, figlio.\n”,getpid());

exit(17); /*termina con stato 17 */ }

Page 14: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

14

Esempio : wait() ed exit() (2) cosa accade se eseguiamo un main contenente il codice dell’esempio :

$ a.out & -- avvio l’esecuzione in bg

Processo 1246, figlio. -- stampato dal figlio

Page 15: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

15

Esempio : wait() ed exit() (3) prima che i 20 secoondi siano finiti ...

$ a.out & -- avvio l’esecuzione in bg

Processo 1246, figlio. -- stampato dal figlio $ ps -l

… S UID PID PPID ………… CMD

… Z 501 1246 1245 …………… a.out

-- il figlio e’ un processo zombie

Page 16: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

16

Esempio : wait() ed exit() (4) quando il padre si risveglia ed esegue la wait() ...

$ a.out & -- avvio l’esecuzione in bg

Processo 1246, figlio. -- stampato dal figlio $ ps -l

… S UID PID PPID ………… CMD

… Z 501 1246 1245 …………… a.out

-- il figlio e’ un processo zombie (Z)

$

Stato 17. -- stampato dal padre

$

Page 17: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

18

Differenziazione : le exec()• execve

– è l’unica chiamata di sistema vera

• execl, execlp,execle,execv, execvp– sono funzioni di libreria con differenze sul tipo di parametri– alla fine invocano la execve

• tutte le exec*()– differenziano un processo rimpiazzando il suo spazio di

indirizzamento con quello di un file eseguibile passato come parametro

Page 18: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

19

Differenziazione : le exec() (2)• execl, execlp,execle,execv, execvp, execve

– è possibile richiedere che la exec() cerchi il file nelle directory specificate dalla variabile di ambiente PATH è (p nel nome)

– è possible passare un array di argomenti secondo il formato di argv[] (v nel nome)

– è possible passare un array di stringhe che descrivono l’environment (e nel nome)

– è possibile passare gli argomenti o l’environment come lista (terminato da NULL) (l nel nome)

Page 19: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

20

Differenziazione : le exec() (3)• execl, execlp,execle,execv, execvp, execve

– le exec() non ritornano in caso di successo!!!– Restituiscono -1 in caso di fallimento

• non trova il file, il file non è eseguibile etc...

– ATTENZIONE 1: le exec non creano nuovi processi!!– ATTENZIONE 2: padre e figlio continuano a

condividere la tabella dei file aperti ….

Page 20: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

21

Text segment

I-Data segmentAmpiezza BSS

Altre info

Magic number

Variabili globaliinizializzate

Ampiezza area dimemoria occupata dalle variabiliglobali NON inizializzate

Numero che contraddistingue il file come eseguibile

Codice del programma (assemblato)

Differenziazione : le exec() (4)• Formato di un file eseguibile

– risultato di compilazione, linking etc ...

Page 21: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

22

Differenziazione : le exec() (5)– (1) il contenuto del file eseguibile viene usato per sovrascrivere

lo spazio di indirizzamento del processo che la invoca

Text

I-Data segment

StackArea vuota

0

232 - 1

BSS-segment

Text segment

I-Data segmentAmpiezza BSS Data

FRAME per la funzione main

envVariabili di ambiente (envp)

argvAgomenti (argv)

File eseguibile

Page 22: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

23

Differenziazione : le exec() (6)– (2) si carica in PC l’indirizzo iniziale X

Text

I-Data segment

StackArea vuota

0

232 - 1

BSS-segment

Text segment

I-Data segmentAmpiezza BSS

env

Indirizzo della prima istruzione compilata di main()

argv

X

X

Page 23: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

24

Esempio : una shell semplificataint pid, status;

char * argv[];

while (TRUE) { /*ciclo infinito*/

type_prompt(); /* stampa prompt*/

argv = read_comm(); /*legge command line*/

IFERROR3(pid = fork(),”Nella fork”,continue);

if (pid) {/* codice padre */

wait(&status);

if (WIFEXITED(status)) …/*gest. stato*/ }

else {/*codice figlio*/

IFERROR(execvp(argv[0],argv),”nella execvp”);

}

Page 24: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

25

Duplicazione dei descrittori di file: dup() e dup2()

int dup(int oldfd);

int dup2(int oldfd,int newfd);– creano entrambi una copia del descrittore di file oldfd ,– entrambi i descrittori puntano alla stassa locazione della tabella dei file aperti e possono essere utilizzati per lavorare sullo stesso file– dup cerca la prima posizione libera– dup2 chiude prima newfd (se aperto) e poi ci copia oldfd

Page 25: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

26

Es: la redirezione– La shell permette di ridirigere stdin/out/error– Es.

$ ls

indirizzi.pdf k.c s.doc

Page 26: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

27

Es: la redirezione– La shell permette di ridirigere stdin/out/error– Es.

$ ls

indirizzi.pdf k.c s.doc

$ ls > pippo

Page 27: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

28

Es: la redirezione– La shell permette di ridirigere stdin/out/error– Es.

$ ls

indirizzi.pdf k.c s.doc

$ ls > pippo

$ more pippo

indirizzi.pdf

k.c

s.doc

Page 28: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

29

Es: la redirezione (2)– La shell permette di ridirigere stdin/out/error. Es (2)

$ more pippo

i.pdf

s.doc

k.c

$ sort < pippo

k.c

i.pdf

s.doc

Page 29: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

30

Es: la redirezione (3)– Redirezione dello stdout ed error su file diversi

$ more pippo.c pluto.c 1> out 2> log

Page 30: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

31

Es: la redirezione (3)– Redirezione dello stdout ed error su file diversi

$ more pippo.c pluto.c > out &> log

Page 31: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

32

Es: la redirezione (3)– Redirezione dello stdout ed error su file diversi

$ more pippo.c pluto.c 1> out 2> log

$ more log

pippo.c: No such file or directory

Page 32: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

33

Es: la redirezione (3)– Redirezione dello stdout ed error su file diversi

$ more pippo.c pluto.c 1> out 2> log

$ more log

pippo.c: No such file or directory

$ more out /* frammento che stampa il pid del processo in esecuzione e quello del padre usando la macro WRITE di stampa (in sysmacro.h) … */

char buf[N]; /* stringa da stampare */ …

sprintf(buf,”Processo %d, mio padre e’ %d\n.”,

getpid(),getppid());

Page 33: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

34

Es: la redirezione (3.1)– Attenzione: out e log vengono sovrascritti!!!!!– Per appendere usare ‘>>’

$ more pippo.c pluto.c 1>> out 2>> log

Page 34: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

35

Es: la redirezione (3.1)– Attenzione: out e log vengono sovrascritti!!!!!– Per appendere usare ‘>>’

$ more pippo.c pluto.c 1>> out 2>> log

$ more log

pippo.c: No such file or directory

pippo.c: No such file or directory

Page 35: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

36

Es: redirezione con dup() e dup2()– Es. voglio ridirigere lo standard output (file descriptor 1) su un file pippo int fd;

...

IFERROR(fd=open(“pippo”,O_WRONLY|O_TRUNC|O_CREAT,0644),”nella open”);

dup2(fd,STDOUT); /* duplica fd sullo standard output*/

close(fd); /* fd non serve piu’ */

printf(“Questo viene scritto in pippo!”);

...

Page 36: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

37

Come la shell implementa la redirezione ...

• Es. $ ls -l > pippo– Il processo shell si duplica con una fork()e si mette in attesa della terminazione del figlio con una wait– Il figlio apre in scrittura il file pippo (creandolo o troncandolo)– Il figlio duplica il descrittore di pippo con la dup2 sullo stdout e chiude il descrittore originario– Il figlio invoca una exec di ls -l, la quale conserva i descrittori dei file, e quindi va a scrivere in pippo ogni volta che usa il file descriptor 1

Page 37: 1 SC che operano su processi Getpid, fork, exec, wait, waitpid, exit, dup, dup2

38

Come la shell implementa la redirezione … (2)

• Es. $ ls -l > pippo (cont.)– Quando il figlio termina, il padre riprende la computazione con i sui descrittori di file invariati.– (padre e figlio hanno ognuno la sua tabella dei descrittori e casomai puntano alla stessa locazione della tabella dei

file aperti)