Laboratorio di Sistemi Operativi: Code di Messaggi (PDF)
Document Details
Uploaded by Deleted User
Università di Torino
Daniele Radicioni
Tags
Summary
Appunti sul laboratorio di Sistemi Operativi, riguardanti le code di messaggi. Vengono descritti concetti, caratteristiche e implementazione, con esempi di codice.
Full Transcript
laboratorio di sistemi operativi code di messaggi Daniele Radicioni credits il materiale di questa lezione è tratto prevalentemente dai testi: - lucidi degli anni passati del Prof. Gunetti. - Michael Kerrisk, The Linux Programming interface - a Linux and UNIX® System Programming...
laboratorio di sistemi operativi code di messaggi Daniele Radicioni credits il materiale di questa lezione è tratto prevalentemente dai testi: - lucidi degli anni passati del Prof. Gunetti. - Michael Kerrisk, The Linux Programming interface - a Linux and UNIX® System Programming Handbook, No Starch Press, San Francisco, CA, 2010. - W. Richard Stevens (Author), Stephen A. Rago, Advanced Programming in the UNIX® Environment (2nd Edition), Addison- Wesley, 2005. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 2 argomenti del laboratorio UNIX introduzione a UNIX; integrazione C: operatori bitwise, precedenze, preprocessore, pacchettizzazione del codice, compilazione condizionale e utility make; controllo dei processi; segnali; pipe e fifo; code di messaggi; memoria condivisa; semafori; introduzione alla programmazione bash. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 3 Introduction to System V IPC System V IPC: message queues "System V IPC" è l'etichetta utilizzata per riferirsi a tre diversi meccanismi per l'interprocess communication: 1. Le code di messaggi, che possono essere utilizzate per scambiare messaggi fra processi. Le code di messaggi sono simili ai pipe, da cui differiscono per 2 aspetti. primo, i confini dei messaggi sono delimitati, così che i lettori e gli scrittori comunicano in unità di messaggi, e non in stream di byte privi di delimitazioni interne. secondo, ciascun messaggio contiene un membro type di tipo intero, ed è possibile selezionare i messaggi per tipo, piuttosto che leggerli nell'ordine in cui sono stati scritti. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 5 System V IPC: semaphores 2.I semafori permettono a molteplici processi di sincronizzare le proprie azioni. un semaforo è un valore intero mantenuto dal kernel visibile a tutti i processi che hanno i permessi necessari. Un processo indica ai propri pari che sta eseguendo una qualche azione facendo una modifica al valore del semaforo. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 6 System V IPC: shared memory 3.La memoria condivisa consente a molteplici processi di condividere lo stesso segmento di memoria. Poiché l'accesso allo spazio della memoria utente è un'operazione veloce, la memoria condivisa è uno dei più veloci strumenti per l'IPC: una volta che un processo ha aggiornato la memoria condivisa, la modifica è immediatamente visibile agli altri processi che condividono lo stesso segmento. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 7 creazione/apertura Ciascun meccanismo delle System V IPC ha associata una system call get (msgget(), semget(), o shmget()), che è l'analogo della system call open() utilizzata per i file. Data una key intera (analoga a un filename), la chiamata get: - crea un nuovo oggetto IPC con la key indicata e restituisce un identificatore unico per quell'oggetto; oppure - restituisce l'identificatore di un oggetto IPC esistente e avente quella key. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 8 sions enabled. The next set indicates the permis and execute enabled, but not write. The final se which doesnDt have any permissions enabled. The header file defines constan st_mode of|the id = msgget(key, IPC_CREAT | S_IRUSR stat structure, in order to check wh S_IWUSR); are set. (These constants are also defined via the in if (id == -1) types the open() system call.) These constants are s errExit("msgget"); Table 15-4: Constants for file permission bits come per tutte le altre syscall Constant Octal value Permission bit get, key è il primo argomento, e S_ISUID 04000 Set-user-ID S_ISGID 02000 Set-group-ID l'identificatore è restituito come S_ISVTX 01000 Sticky risultato della funzione. S_IRUSR 0400 User-read S_IWUSR 0200 User-write Specifichiamo i permessi di S_IXUSR 0100 User-execute S_IRGRP 040 Group-read accesso al nuovo oggetto come S_IWGRP 020 Group-write ultimo argomento (flags), S_IXGRP 010 Group-execute S_IROTH 04 Other-read utilizzando le costanti elencate S_IWOTH 02 Other-write qui a fianco S_IXOTH 01 Other-execute Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 9 In addition to the constants shown in Table 15-4 equate to masks for all three permissions for each and other: S_IRWXU (0700), S_IRWXG (070), and S_IRWX The header file in Listing 15-3 declares a func Creating/opening a System V IPC idobject = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR); if (id == -1) ddErrExit("msgget"); Ogni processo che desideri accedere allo stesso oggetto IPC esegue una chiamata get, specificando la stessa key per ottenere lo stesso identificatore per quell'oggetto. Se non esiste un oggetto IPC corrispondente alla key, ed è stata specificata la costante IPC_CREAT come parte dei flag, la get crea un nuovo oggetto IPC. Un processo può garantire di essere il creatore di un oggetto IPC specificando il flag IPC_EXCL: - Se il flag IPC_EXCL è specificato, e l'oggetto IPC corrispondente alla key esiste già, la get fallisce con l'errore EEXIST. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 10 Cancellazione di oggetti IPC if (shmctl(id, IPC_RMID, NULL) == -1) errExit("shmctl"); La system call ctl (msgctl(), semctl(), shmctl()) per ciascun meccanismo di IPC esegue un gran numero di operazioni di controllo sull'oggetto. Mentre molte di queste operazioni sono specifiche dei vari meccanismi di IPC, alcune sono comuni a tutti. - Per esempio, una generica operazione di controllo è IPC_RMID, utilizzata per cancellare un oggetto. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 11 Cancellazione e persistenza di oggetti IPC Per le code di messaggi e i semafori, la cancellazione degli oggetti IPC è immediata, e qualsiasi informazione contenuta all'interno dell'oggetto è distrutta, a prescindere dal fatto che qualche altro processo stia ancora utilizzando quell'oggetto. La cancellazione di oggetti legati alla memoria condivisa ha un diverso comportamento. - Seguendo la chiamata shmctl(id, IPC_RMID, NULL), il segmento di memoria condivisa è rimosso solo dopo che tutti i processi che lo utilizzano lo staccano. Questa modalità è molto più simile alla situazione della cancellazione di un file. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 12 Persistenza degli oggetti IPC Gli oggetti IPC hanno una kernel persistence: dopo essere stati creati, continuano ad esistere finché sono esplicitamente cancellati o il sistema viene spento. - Tale proprietà degli oggetti IPC fornisce alcuni vantaggi: è possibile per un processo creare un oggetto, modificarne lo stato e uscire, lasciando che l'oggetto resti accessibile da altri processi iniziati successivamente. - gli svantaggi: esistono limiti di sistema sul massimo numero di oggetti IPC di ogni tipo... - il problema è che questi oggetti sono connectionless—cioè il kernel non tiene traccia di quali processi hanno un oggetto aperto. Quando si cancella una coda di messaggi, un'applicazione con molti processi può non essere agevolmente in grado di determinare quale sarà l'ultimo processo a richiedere l'accesso all'oggetto e quindi quando l'oggetto può essere cancellato senza problemi. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 13 IPC Keys Le keys dei meccanismi IPC di System V sono valori interi rappresentati con il tipo key_t. La chiamata get mappa una key sul corrispondente identificatore IPC intero. - Queste chiamate garantiscono che se creiamo un nuovo oggetto, quell'oggetto abbia un identificatore unico, e che - se specifichiamo la key di un oggetto esistente, otteniamo sempre lo stesso identificatore per quell'oggetto. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 14 IPC Keys Come si genera una key unica, tale da garantirci di non ottenere accidentalmente l'identificatore di un oggetto IPC esistente, utilizzato da qualche altra applicazione? - Scelta casuale di una valore intero, che è tipicamente memorizzato in un header file incluso da tutti i programmi che usano l'oggetto IPC. - Utilizzo della costante IPC_PRIVATE come valore della key nella invocazione alla get al momento della creazione dell'oggetto, che produce sempre un oggetto con una chiave unica. - Utilizzo della funzione ftok() per generare una key molto probabilmente unica. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 15 Generazione di key con IPC_PRIVATE id = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR); In questo caso non è necessario specificare i flag IPC_CREAT o IPC_EXCL. - Questa tecnica è particolarmente utile in applicazioni con molti processi in cui il processo padre crea l'oggetto IPC prima di eseguire la fork(), con il risultato che il figlio eredita l'identificatore dell'oggetto IPC. - È possibile utilizzare questa tecnica anche in applicazioni client-server (che coinvolgono processi non collegati), ma i client devono avere un mezzo per ottenere gli identificatori degli oggetti IPC creati dal server (e viceversa). Per esempio, dopo avere creato un oggetto IPC, il server potrebbe scrivere il proprio identificatore su un file, che potrebbe essere letto dai client. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 16 Generazione di key con ftok() #include key_t ftok(char *pathname, int proj); Returns integer key on success, or –1 on error Questo valore di key è generato dal pathname fornito e dal valore proj utilizzando un algoritmo definito a livello di implementazione. Nella generazione della key, ftok() utilizza il numero i-node piuttosto che il nome del file. - Poiché l’algoritmo della ftok() dipende dal numero i-node, il file in questione non dovrebbe essere rimosso e ricreato mentre l'applicazione è in esecuzione, poiché è probabile che il file sia ricreato con un diverso numero i-node. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 17 Generazione di key con ftok() Il fine del valore proj è consentire di generare diverse key a partire dallo stesso file; è utile quando un'applicazione deve creare vari oggetti IPC dello stesso tipo. - Storicamente, l'argomento proj era di tipo char, ed è spesso specificato come tale nelle chiamate a ftok(). key_t key; int id; key = ftok("/mydir/myfile", 'x');... id = msgget(key, IPC_CREAT | S_IRUSR | S_IWUSR);... Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 18 Associated Object Permissions struct ipc_perm { Il kernel mantiene una struttura dati key_t key; per ogni istanza di un oggetto IPC. uid_t uid; - La forma di questa struttura dati varia gid_t gid; a seconda del meccanismo (code di uid_t cuid; messaggi, semafori o memoria gid_t cgid; condivisa) ed è definito nell'header file unsigned short mode; corrispondente a ciascun meccanismo unsigned short __seq; IPC. La struttura dati associata a un oggetto IPC è inizializzata quando l'oggetto è creato per mezzo dell'appropriata system call get. - Una volta che l'oggetto è stato creato, un programma può ottenere una copia di questa struttura dati utilizzando l'apposita syscall ctl, e specificando un'operazione di tipo IPC_STAT. - Alcuni elementi della struttura dati possono essere modificati per mezzo della operazione IPC_SET. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 19 struct shmid_ds shmds; if (shmctl(id, IPC_STAT, &shmds) == -1)// prelevo dal kernel //... gestione errore... shmds.shm_perm.uid = newuid; // modifico l'owner ID // (nella copia locale) if (shmctl(id, IPC_SET, &shmds) == -1) // modifico la copia // mantenuta dal kernel //... gestione errore... Modifica del campo uid per un segmento di memoria condivisa. La struttura dati associata è di tipo shmid_ds. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 20 Associated Object Permissions Il campo mode della sottostruttura ipc_perm contiene i permessi per l'oggetto IPC. I permessi sono inizializzati utilizzando i 9 bit più bassi specificati nei flag della syscall get, ma possono essere modificati successivamente utilizzando l'operazione IPC_SET. Come con i file, i permessi sono divisi in tre categorie: owner (o user), group, e other, ed è possibile specificare diversi permessi per ogni categoria. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 21 comandi ipcs 45.6 The ipcs andand ipcrmipcrm Commands The ipcs and ipcrm commands are the System V IPC analogs of the ls and rm file commands. Using ipcs, we can obtain information about IPC objects on the system. I comandi ipcsipcs By default, e ipcrm displays sono analoghi all objects, ai comandi as in the following ls e rm per i file. example: $ ipcs ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x6d0731db 262147 mtk 600 8192 2 ------ Semaphore Arrays -------- key semid owner perms nsems 0x6107c0b8 0 cecilia 660 6 0x6107c0b6 32769 britta 660 1 ------ Message Queues -------- key msqid owner perms used-bytes messages 0x71075958 229376 cecilia 620 12 2 On Linux, Daniele ipcs(1)Radicioni displays information only about IPC objects for which we have read - Laboratorio di Sistemi Operativi, corso A - turno T1 22 permission, regardless of whether we own the objects. On some UNIX implementa- tions, ipcs shows the same behavior as on Linux. However, on other implementations, ipcs displays all objects regardless of whether read permission is granted to the user. comandi ipcs and ipcrm Di default, per ciascun oggetto, ipcs visualizza la key, l'identificatore, l'owner e i permessi (espressi in notazione ottale), seguiti da informazioni specifiche per l'oggetto: - per la memoria condivisa, ipcs visualizza la dimensione della regione di memoria condivisa, il numero di processi che attualmente hanno la regione attaccata ai propri spazi di indirizzi e dei flag di stato. - per i semafori, ipcs visualizza la dimensione del set di semafori. - per le code di messaggi, ipcs visualizza il numero totale di byte di dati e il numero di messaggi presenti nella coda. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 23 comandi ipcs and ipcrm Il comando ipcrm cancella un oggetto IPC object. La forma generale di questo comando è la seguente: $ ipcrm -X key $ ipcrm -x id specifichiamo key (oppure l'identificatore id), e la lettera X (oppure x) è una q per le message queues, da una s per i semaphores, o da una m per la shared memory. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 24 code di messaggi Canale di comunicazione su cui possono affacciarsi più processi che inviano e ricevono messaggi P1 P2 ------- ------- ------- ------- send receive receive m1 m2 m2... send P4 P3 send ------- ------- receive ------- ------- Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 26 Message Queues Le code di messaggi differiscono da pipe e FIFO per queste caratteristiche: 1. l'identificativo utilizzato per riferirsi a una coda di messaggi è l'identificatore restituito da una chiamata a msgget(). 2. La comunicazione per mezzo di code di messaggi è 'message- oriented'; cioè, il lettore riceve messaggi interi, scritti dallo scrittore. 3. Non è possibile leggere porzioni di messaggi, lasciandone altre porzioni in coda, o leggere più messaggi alla volta. 4. Oltre a contenere dati, ogni messaggio contiene un membro di tipo intero che permette di prelevare i messaggi dalla coda in ordine first-in, first-out oppure per tipo. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 27 Creating/Opening a Message Queue #include #include int msgget(key_t key, int msgflg); Returns message queue identifier on success, or – 1 on error l'argomento key è una chiave generata utilizzando un numero casuale, IPC_PRIVATE o ftok(); L'argomento msgflg è una maschera di bit che specifica i permessi da associare a una nuova coda di messaggi. Se la coda esiste già, permette di verificarne i permessi. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 28 msgflg argument zero o più fra i seguenti flag possono essere concatenati in OR (|) nel msgflg per controllare la msgget(): - IPC_CREAT: se non esiste una coda con la key specificata, crea una nuova coda; - IPC_EXCL: se è presente anche IPC_CREAT, e una coda con la key specificata esiste già, restituisci un fallimento con errore EEXIST. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 29 msgget() system call la system call msgget() inizia cercando all'interno delle code di messaggi esistenti quella con la key specificata. - Se tale key corrisponde a una coda, la msgget() restituisce l'identificatore di quella coda (a meno che siano stati specificati sia IPC_CREAT sia IPC_EXCL, nel qual caso viene restituito un errore). - Se la coda non esiste e IPC_CREAT è specificato, la msgget() crea una nuova coda e ne restituisce l'identificatore al chiamante. Daniele Radicioni - Laboratorio di Sistemi Operativi, corso A - turno T1 30 esempio di invocazione msgget() // creo una coda di messaggi tramite msgget if((m_id = msgget(ftok("f_name.c",1), IPC_CREAT))