SC per IPC

41
1 SC per IPC Pipe

description

SC per IPC. Pipe. Pipe. B. A. pipe. Pipe : file speciali utilizzati per connettere due processi con un canale di comunicazione. Se B cerca di leggere da una pipe vuota si blocca Quando la pipe è piena A viene automaticamente sospeso L’ampiezza della pipe dipende dal sistema (in Lunux 4K). - PowerPoint PPT Presentation

Transcript of SC per IPC

Page 1: SC per IPC

1

SC per IPC

Pipe

Page 2: SC per IPC

2

Pipe

• Pipe : file speciali utilizzati per connettere due processi con un canale di comunicazione

• Se B cerca di leggere da una pipe vuota si blocca• Quando la pipe è piena A viene automaticamente sospeso• L’ampiezza della pipe dipende dal sistema (in Lunux 4K)

A Bpipe

Page 3: SC per IPC

3

Pipe con nome e senza nome– pipe senza nome (unnamed) file senza un nome visibile, che viene utilizzato per comunicazioni fra processi che condividono

puntatori alla tabella dei file aperti (es. padre figlio, nonno nipote etc) – pipe con nome (named) file speciale (p) con nome visibile a tutti gli altri processi sulla stessa macchina– in entrambi i casi lettura/scrittura dalla pipe viene effettuata con le SC read() write() utilizzate anche per gli altri file

Page 4: SC per IPC

4

Creazione di pipe senza nome: pipe() int pipe(int filedes[2]);– crea un file speciale di tipo pipe– restituisce due file descriptor:

• filedes[1] per la scrittura sul pipe e• filedes[0] per la lettura dal pipe

– restituisce 0 in caso di successo– restituisce -1 in caso di fallimento

• es. il processo stra usando troppi file descriptor ...

Page 5: SC per IPC

5

Creazione di pipe senza nome (2)/* frammento che crea un nuovo pipe */

int fd[2]; /* per i descrittori */

IFERROR( pipe(fd),”creazione pipe”);

/* da qua fd[1] puo’ essere usato per la scrittura e fd[0] per la lettura */

Page 6: SC per IPC

6

Uso di una pipe senza nome • Processo scrittore :

– usa le write()– può scrivere solo se il file descriptor per la lettura (fd[0]) non è stato ancora chiuso

• altrimenti riceve un segnale SIGPIPE che per default termina il processo

– la scrittura è atomica (a meno di non aver raggiunto la capienza massima del pipe)

Page 7: SC per IPC

7

Uso di una pipe senza nome (2) • Processo lettore :

– usa la read()– se il file descriptor per la scrittura (fd[1]) è stato chiuso la read restituisce 0 (che indica la fine dell’input dalla pipe)– se la pipe è vuota ma fd[1] non è stato ancora chiuso la read si blocca in attesa di dati sul pipe– se si cerca di leggere più byte di quelli presenti nel pipe la read ha successo ma il numero di byte letti restituito è minore del valore del terzo parametro

Page 8: SC per IPC

8

Uso di una pipe senza nome (3) • Non ha senso usare lseek!! • Solo per processi discendenti

– si passano i file descriptor attraverso la condivisione dei puntatori alla tabella dei file aperti

• Si usa per comunicazione unidirezionale• Non esiste il concetto di messaggio

– byte non strutturati– i processi comunicanti devono stabilire un protocollo esplicito per scambiarsi messaggi di una certa lunghezza o messaggi di lunghezza variabile

Page 9: SC per IPC

9

Uso di una pipe senza nome (4) • Sequenza tipica di utilizzo di una pipe senza nome:

– il padre crea la pipe– il padre si duplica con una fork()

• i file descriptor del padre sono copiati nella file descriptor table del figlio

– il processo scrittore (padre o figlio) chiude fd[0] mentre il processo lettore chiude fd[1] – i processo comunicano con read/write– quando la comunicazione è finita ognuno chiude la propria estremità

Page 10: SC per IPC

10

Uso di una pipe senza nome (5) int fd[2]; /* per i descrittori */

char msg[100]; /* msg di lunghezza 100*/

IFERROR( pipe(fd),”creazione pipe”);

IFERROR( pid=fork(),”creazione figlio”);

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

close(fd[1]); /* chiude scrittura */

read(fd[0],msg,100;

WRITELN(msg); /* scrive il msg letto*/

} else { /* siamo nel figlio */

close(fd[0]); /* chiude lettura */

sprintf(msg,”Da %d: Hi!!\n”,getpid());

write(fd[1],msg,100);

close(fd[1]);}

Page 11: SC per IPC

11

Messaggi di lunghezza variabile• Possibile protocollo:

– ogni messaggio logico è implementato da due messaggi fisici sul canale– il primo messaggio (di lunghezza nota), specifica la lunghezza lung– il secondo messaggio (di lunghezza lung) codifica il messaggio vero e proprio

• vediamo un frammento di possibile implementazione

Page 12: SC per IPC

12

Messaggi di lunghezza variabile (2) …

} else { /* siamo nel figlio */

int lung; /* per la lunghezza*/

close(fd[0]); /* chiude lettura */

sprintf(msg,”Da %d: Hi!!\n”,getpid());

lung = strlen(msg) + 1; /* terminatore */

/* primo messaggio*/

write(fd[1], &lung,sizeof(int));

/* secondo messaggio */

write(fd[1],msg,lung);

close(fd[1]);

}

Page 13: SC per IPC

13

Messaggi di lunghezza variabile (3) …

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

int l,lung; /* per la lunghezza */

char* msg; /* per il messaggio*/

close(fd[1]); /* chiude scrittura */

IFERROR(l=read(fd[0],&lung,sizeof(int)),

”lettura”);

msg = malloc(lung);

IFERROR(l=read(fd[0],&msg,lung),

”lettura”);

WRITELN(msg); /* scrive il msg letto*/

free(msg); /* se non serve piu’ */

close(fd[0]); }

Page 14: SC per IPC

14

Creazione di pipe con nome: mkfifoint mkfifo(const char * pathname,

mode_t mode);– crea un file speciale di tipo pipe con il nome e la posizione specificati in pathname ed i diritti di accesso specificati da mode– restituisce 0 se ha avuto successo e -1 altrimenti

• se il file esiste già da errore

– attenzione ai diritti! I diritti del file creato non sono direttamente 0644 ma vengono modificati a seconda del valore di una variabile della shell (umask)• vale ogni volta che creiamo un file (es. open …)

Page 15: SC per IPC

15

Shell : umask• es. se create un file con

open(“ff”,O_CREAT|O_RDWR,0666)

probabilmente i diritti del file ff dopo l’esecuzione deall SC saranno

r w - r - - r - -

e non, come specificato dal terzo parametro

r w - r w - r w -

1 1 0 1 1 0 1 1 0

6 6 6

?????????

Page 16: SC per IPC

16

Shell : umask (2)• umask è una maschera che fornisce una restrizione ai diritti di accesso (modo) di un file al momento della creazione• il modo del file viene calcolato come (modo&~(umask))• Tipicamente umask = 022 quindi :

1 1 0 1 1 0 1 1 0 (modo 0666)

0 0 0 0 1 0 0 1 0 (umask)

1 1 1 1 0 1 1 0 1 (~umask)

1 1 0 1 0 0 1 0 0 (modo & (~umask))

r w - r - - r - -

Page 17: SC per IPC

17

Shell : umask (3)• Si può modificare il valore di umask con il comando umask

– $umask fornisce il valore corrente della maschera

– $umask valore_ottalesetta umask al valore_ottale specificato

• Il valore di umask viene ereditato dal padre e vale fino alla prossima modifica• I file creati con la ridirezione usano la open() con modo 0666, e quindi sono sensibili al valore di umask

Page 18: SC per IPC

18

Creazione di pipe con nome: mkfifo (2)Es:

mkfifo(“pippo”, 0664);– se i diritti del file non sono quelli desiderati:

> ls -l pippo

prw-r--r-- 1 susanna …… pippo

possiamo cambiarli con chmod() es

chmod(“pippo”, 0664);

adesso …> ls -l pippo

prw-rw-r-- 1 susanna …… pippo

Page 19: SC per IPC

19

Creazione di pipe con nome (3)/* frammento che crea un nuovo pipe con nome */

IFERROR( mkfifo(“ff”,0664),”creazione pipe”);

IFERROR( chmod(“ff”,0664),”diritti pipe”);

Page 20: SC per IPC

20

Uso di una pipe con nome • Prima di iniziare a scrivere/leggere la pipe deve essere aperta contemporaneamente da un lettore e da uno scrittore:• Apertura da parte di un processo scrittore :

– usa le open()– se nessun lettore ha ancora invocato la open() si blocca in attesa del primo lettore– usando le opzioni O_NONBLOCK, O_NDELAY se non ci sono lettori la open termina subito con fallimento

Page 21: SC per IPC

21

Uso di una pipe con nome (2) • Apertura da parte di un processo lettore :

– usa le open()

– se nessun scrittore ha ancora invocato la open() si blocca in attesa dello scrittore

– usando le opzioni O_NONBLOCK, O_NDELAY se non ci sono scrittori la open termina subito con successo

Page 22: SC per IPC

22

Uso di una pipe con nome (3) • Tipico uso : più client e un server

– il server crea la pipe e la apre in lettura

– i client aprono in scrittura la stessa pipe

• La capienza è 40K

Page 23: SC per IPC

23

Rimozione di uan pipe: unlink() int unlink(const char*patname);– decrementa il conto degli hard link del file indicato da pathname – se il numero degli hard link si è azzerato e nessun processo ha il file aperto si elimina il file dal file system– se un processo ha ancora il file aperto,

• un file regolare continua ad esistere finche l’ultimo descrittore è chiuso• un pipe con nome può essere usato solo da chi loha già aperto (viene rimosso il nome)

– ritorna 0 (successo) o -1 (fallimanto)

Page 24: SC per IPC

24

Precisazioni sul funzionamento della shell

Page 25: SC per IPC

25

Shell • È un interprete di comandi che gira in modo utente• Nella versione base, esegue un ciclo infinito:

– accetta un nuovo comando (cmd)– crea un processo P che esegue cmd– si mette in attesa della terminazione di P

• Può anche eseguire una serie di comandi salvati su file (script)

Page 26: SC per IPC

26

Shell (2) • Ci sono vari tipi di shell (Bourne, C)

– vedremo delle caratteristiche comuni a tutte

• Come si attiva una shell ?– Automaticamente con il login o eseguendo il codice corrispondente (es. sh, csh)

• All’attivazione esegue prima di tutto un file di inizializzazione – .bashrc per la Bourne .cshrc per la C-shell

• La shell termina quando legge un EOF

Page 27: SC per IPC

27

Shell: metacaratteri• Sono caratteri che la shell interpreta in modo ‘speciale’

– &, >, >>, <, ~, | , *….

• Forniscono alla shell indicazioni su come comportarsi nella fase di interpretazione del comando– vediamone alcuni ...

Page 28: SC per IPC

28

Shell: metacaratteri (2)• Wildcard : permettono di scrivere espressioni regolari che denotano un insieme di nomi di file

– ‘*’ qualsiasi stringa • es. $ls *.c

uno.c g.c h.c

– ‘?’ qualsiasi carattere • es. $ls ?.c

g.c h.c

Page 29: SC per IPC

29

Shell: ridirezione• Ogni processo Unix ha dei ‘canali di comunicazione’ predefiniti con il

mondo esterno – es. $sort

Pstdin

stdout

stderrTipicamente la tastiera

Tipicamente lo schermo

Tipicamente lo schermo

Page 30: SC per IPC

30

Shell: ridirezione (2)• >, <, >>, &>, &>> permettono di ridirigere questi canali

– es. $sort > pippo

Pstdin

‘pippo’

stderrTipicamente la tastiera

Tipicamente lo schermo

Scrive l’output del comando ls nel file ‘pippo’

Page 31: SC per IPC

31

Shell: ridirezione (3)• >, <, >>, &>, &>> permettono di ridirigere questi canali

– es. $sort > pippo < pippuzzo

Ppippuzzo

pippo

stderrL’input viene letto dal file ‘pippuzzo’

Tipicamente lo schermo

Scrive l’output del comando ls nel file ‘pippo’

Page 32: SC per IPC

32

Shell: ridirezione (4)• >, <, >>, &>, &>> permettono di ridirigere questi canali

– es. $sort >> pippo < pippuzzo

Ppippuzzo

pippo

stderrL’input viene letto dal file ‘pippuzzo’

Tipicamente lo schermo

Scrive l’output del comando ls nel file‘pippo’. Se pippo esiste aggiungein fondo

Page 33: SC per IPC

33

Shell: ridirezione (5)• >, <, >>, &>, &>> permettono di ridirigere questi canali

– es. $sort &> pippo < pippuzzo

Ppippuzzo

pippo

stderr

L’input viene letto dal file ‘pippuzzo’ Anche i messaggi di errore

vengono scritti su ‘pippo’

Scrive l’output del comando ls nel file‘pippo’. Se pippo esiste aggiungein fondo

Page 34: SC per IPC

34

Shell: processi in background• & permette di attivare un processo in background

– es. $emacs &

$

la shell non invoca la waitpid() immediatamente

Page 35: SC per IPC

35

Shell: pipelining• |, |& permettono di eseguire in pipeline più processi relativi a comandi

diversi– es. $ls *.c | grep ciccio | sort

ls

stdout

pipe

Elimina tutte lelinee che non contengono‘ciccio’

grepsortstdin

stdinstdout

pipe

stderr stderr stderr

stdout

Page 36: SC per IPC

36

Shell: pipelining• |, |& permettono di eseguire in pipeline più processi relativi a comandi

diversi– es. $ls *.c |& grep cic | sort

ls

stdout

pipe

Elimina tutte lelinee che non contengono‘cic’

grepsortstdin

stdinstdout

pipe

stderr stderr stderr

stdout

Page 37: SC per IPC

37

Shell : environment• Le shell hanno delle variabili di environment che mantengono informazioni sotto forma di stringhe (nome=valore)• Alcune sono predefinite. Es.

– $PATH contiene le directory in cui la shell va a cercare un comando– $MANPATH contiene le directory in cui la shell va a cercare i manuali in linea– $HOME pathname della home directory– $SHELL pathname della login shell

Page 38: SC per IPC

38

Shell : environment (2)• Le variabili di environment si possono leggere e modificare. La sintassi dipende dal tipo di shell usata

– es. nella bash$echo $PATH ... valore di PATH

PATH=/usr/local/bin:/usr/bin/

$export PATH=$PATH:.

$echo $PATH ... valore di PATH

PATH=/usr/local/bin:/usr/bin/:.

Page 39: SC per IPC

39

Shell : umask• es. se create un file con

open(“ff”,O_CREAT|O_RDWR,0666)

probabilmente i diritti del file ff dopo l’esecuzione saranno

r w - r - - r - -

e non, come specificato dal terzo parametro

r w - r w - r w -

1 1 0 1 1 0 1 1 0

6 6 6

?????????

Page 40: SC per IPC

40

Shell : umask (2)• umask è una maschera che fornisce una restrizione ai diritti di accesso (modo) di un file al momento della creazione• il modo del file viene calcolato come (modo&~(umask))• Tipicamente umask = 022 quindi :

1 1 0 1 1 0 1 1 0 (modo 0666)

0 0 0 0 1 0 0 1 0 (umask)

1 1 1 1 0 1 1 0 1 (~umask)

1 1 0 1 0 0 1 0 0 (modo & (~umask))

r w - r - - r - -

Page 41: SC per IPC

41

Shell : umask (3)• Si può modificare il valore di umask con il comando umask

– $umask fornisce il valore corrente della maschera

– $umask valore_ottalesetta umask al valore_ottale specificato

• Il valore di umask viene ereditato dal padre e vale fino alla prossima modifica• I file creati con la ridirezione usano la open() con modo 0666, e quindi sono sensibili al valore di umask