Sistemi operativi, A.A. 2011/2012 (M. Cesati) Scaletta esercitazione #13, 14.06.2012 1 IPC: InterProcess Communication 1.1 Pipe uni-direzionali 1.2 FIFO (named pipe) 1.3 System V IPC 1.3.1 Code di messaggi 1.3.2 Memoria condivisa 1.3.3 Semafori 1.4 POSIX IPC 2 Pipe uni-direzionali 2.1 La chiamata di sistema pipe() +------------------------+ |int pipe(int pipefd[2]);| +------------------------+ 2.2.1 Restituisce due descrittori di file, il primo per l'input, il secondo per l'output 2.2.2 Dopo la pipe() il processo esegue una fork() 2.2.3 Ciascuno dei due processi chiude l'uno o l'altro descrittore di file 2.2 Le chiamate di sistema dup() e dup2() +-------------------------------+ |int dup(int oldfd); | |int dup2(int oldfd, int newfd);| +-------------------------------+ 2.2.1 Duplicano il descrittore di file "oldfd" 2.2.2 dup(): il nuovo descrittore e' il primo inutilizzato 2.2.3 dup2(): il nuovo descrittore e' "newfd", se gia' in uso viene preventivamente chiuso 2.4 Le chiamate di sistema popen() e pclose() +---------------------------------------------------+ |FILE *popen(const char *command, const char *type);| |int pclose(FILE *stream); | +---------------------------------------------------+ 2.4.1 popen(): crea una pipe in lettura (type="r") o scrittura (type="w") connessa tra il processo invocante ed il processo corrispondente al comando di shell "command" 2.3 Esercizio: utilizzare pipe(), dup() e execve() per scrivere in un buffer i nomi dei file contenuti nella directory corrente del programma [nomifile.c] 3 FIFO (named pipe) 3.1 Comandi di sistema mknod e mkfifo $ mknod F1 p $ mkfifo F2 $ ls -l F? prw-r--r-- 1 cesati users 0 2012-06-13 17:28 F1 prw-r--r-- 1 cesati users 0 2012-06-13 17:28 F2 3.3 $ echo -n "repetita iuvant " | cat - F1 | tee F1 4 System V IPC 4.1 Identificatori di risorse IPC 4.1.1 Persistenti fino a cancellazione o reboot 4.2 La funzione ftok() +-----------------------------------------------+ |key_t ftok(const char *pathname, int proj_id); | +-----------------------------------------------+ 4.3 I comandi ipcs, ipcmk, ipcrm 4.3.1 Creazione: ipcmk -M | -S | -Q 4.3.2 Elenco: ipcs 4.3.3 Cancellazione: ipcrm -M key|-m id|-Q key|-q id|-S key|-s id 5 Code di messaggi 5.1 La struttura struct msgbuf +---------------------------------------------------+ |struct msgbuf { | | long mtype; /* message type, must be > 0 */ | | char mtext[1]; /* message data */ | |}; | +---------------------------------------------------+ 5.1.1 Al posto di mtext l'applicazione puo' definire qualunque sequenza di campi 5.2 La chiamata di sistema msgget() +----------------------------------+ |int msgget(key_t key, int msgflg);| +----------------------------------+ 5.2.1 Restituisce un identificatore per la coda di messaggi 5.2.2 key: IPC_PRIVATE (nuova risorsa) oppure chiave 5.2.3 msgflg: IPC_CREAT (crea se necessario) | IPC_EXCL (errore se risorsa gia' esiste) | diritti di accesso 5.3 La chiamata di sistema msgsnd() +------------------------------------------------------------------+ |int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);| +------------------------------------------------------------------+ 5.3.1 msqid: identificatore della coda di messaggi 5.3.2 msgp: puntatore al messaggio da spedire 5.3.3 msgsz: dimensione del messaggio da spedire (senza considerare il campo mtype!) 5.3.4 mgsflg: IPC_NOWAIT (non bloccare se non e' possibile spedire subito il messaggio) 5.4 La chiamata di sistema msgrcv() +-----------------------------------------------------------------+ |ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, | | int msgflg); | +-----------------------------------------------------------------+ 5.4.1 msqid: identificatore della coda di messaggi 5.4.2 msgp: puntatore al buffer che ricevera' il messaggio 5.4.3 msgsz: dimensione del buffer (senza considerare lo spazio necessario per mtype!) 5.4.4 msgtyp: tipo (etichetta) del messaggio 5.4.4.1 Se 0, ricevi il primo messaggio in coda 5.4.4.2 Se >0, il primo messaggio (non) del tipo indicato 5.4.4.3 Se <0, il primo messaggio con tipo minore o uguale a -msgtyp 5.4.5 msgflg: MSG_NOERROR (tronca il messaggio se troppo lungo invece di restituire errore) | MSG_EXCEPT (rovescia la logica di msgtyp) | IPC_NOWAIT (non bloccare se la coda e' vuota) 5.4.6 Restituisce il numero di byte copiati nel buffer messaggi 5.5 Per manipolare la coda di messaggi: chiamata di sistema msgctl() +-----------------------------------------------------+ |int msgctl(int msqid, int cmd, struct msqid_ds *buf);| +-----------------------------------------------------+ 5.6 Esercizio: scrivere un programma che permetta di lanciare due processi indipendenti (non in relazione padre/figlio) che dialogano attraverso una coda di messaggi IPC. Ciascun processo riceve dall'altro un valore numerico, lo stampa, ed invia all'altro lo stesso valore incrementato di uno. [pinginc.c] ==========