![]() | ![]() |
|
|
Nei sistemi Unix ogni processo possiede il relativo spazio di indirizzi virtuale e il sistema garantisce che un processo non acceda all'area di memoria corrispondente ad un altro processo. Con la memoria virtuale si dichiara una sezione di memoria comune a più processi che ogni processo può scrivere e modificare: a questo punto sarà necessario sincronizzare l'accesso di ogni singolo processo in quest'area.
Allocazione di un segmento di memoria condivisa - shmget ( )
Per allocare un segmento di memoria condivisa (operazione necessaria per poter usare il segmento), si impiega la shmget(): essa ottiene la chiave del segmento , la dimensione del segmento, i flag relativi ai permessi d'accesso sul segmento e relativi alla creazione della pagina qualora questa non esista. Il valore di ritorno è un ID che verrà usato dai processi per accedere al segmento.
Se più processi cercano di allocare un segmento usando lo stesso ID (ogni processo esegue la shmget) ognuno di questi otterrà un ID per accedere alla stessa pagina a meno che come flag in shmget venga definito IPC_EXCL. In questo caso la chiamata avrà successo solo se la pagina non esisteva in precedenza.
Accesso ad unsegmento di memoria condivisa
Una volta allocata la pagina di memoria è necessario aggiungerla nella memory page dei processi. Questo procedimento è fattibile usando la shmat ( ): essa usa il parametro 'shm_id' che contiene l'ID ritornato dalla shmget ( ).
Aggiungere le informazioni in un segmento di memoria condivisa è fattibile usando la shmat ( ). Il segmento potrà contenere qualsiasi tipo di informazione fatta eccezione per i puntatori (dal momento che essi contengono indirizzi virtuali). Sebbene lo stesso segmento possa essere puntato da diversi indirizzi virtuali in ogni processo, ogni puntatore deve riferire a un'area di memoria puntata da un altro processo. Il seguente è un esempio relativo all'aggiunta dei dati in un segmento di memoria condivisa con successiva lettura. Si assume che 'shm_addr' è una strnga contenente l'indirizzo ritornato da shmat ( ).
// struttura utile per memorizzare le informazioni che verranno messe nel segmento
struct country ;
// definizione della variabile * define a countries array variable.
int* countries_num;
struct country* countries;
// creazione di un indice per i paesi sul segmento condiviso
countries_num = (int*) shm_addr;
*countries_num = 0;
countries = (struct country*) ((void*)shm_addr+sizeof(int));
strcpy(countries[0].capital_city, "U.S.A");
strcpy(countries[0].capital_city, "Washington");
strcpy(countries[0].currency, "U.S. Dollar");
countries[0].population = 250000000;
(*countries_num)++;
strcpy(countries[1].capital_city, "Israel");
strcpy(countries[1].capital_city, "Jerusalem");
strcpy(countries[1].currency, "New Israeli Shekel");
countries[1].population = 6000000;
(*countries_num)++;
strcpy(countries[1].capital_city, "France");
strcpy(countries[1].capital_city, "Paris");
strcpy(countries[1].currency, "Frank");
countries[1].population = 60000000;
(*countries_num)++;
// stampa a video le informazioni di tutti i paesi
for (i=0; i < (*countries_num); i++)
Uso della malloc: sebbene la memoria è stata già allocata (shmget) non c'è bisogno di usare la malloc per inserire i dati nel segmento. E' buona norma dimensionare il segmento affinché esso possa contenere quantità di dati sempre crescenti (senza usare la realloc, ma pre-dimensionandolo).
La memoria è allineata (lo si suppone).
Completezza del modello dei dati: è necessario aggoungere tutti i dati, evitando di tralascarne qualcuno, nel segmento di memoria condivisa onde evitare che altri processi accedano apparentemente piena ma di fatto vuota.
E' possibile distruggere il segmento di memoria condivisa, a meno che qualche processo non lo stia usando, qualora questi non servisse. Nell'esempio di seguito il segmento verrà distrutto solo dopo che tutti I processi lo avranno rilasciato.
Qualsiasi processo è in grado di distruggere il segmento di memoria condivisa, a patto che questi possa scrivere nel segmento, e non solo quello che l'ha creato.
Esempio
Il file "shared-mem.c" mostra come il singolo processo utilizzi la memoria condivisa: naturalmente qualora due o più processi utilizzassero lo stesso segmento di memoria condivisa, si verificherà una "race condition" (un processo modifica il segmento mentre un secondo processo sta leggendo lo stesso segmento). Onde evitare questa situazione si utilizzeranno dei meccanismi di bloccaggio (SysV semafori con la mutua esclusione).
Il file "shared-mem-with-semaphore.c" è un esempio di due processi che accedono allo stesso segmento di memoria usando un semaforo per sincronizzare i loro accessi.
Creazione di una ID per una risorsa SysV - ftok( )
Uno dei problemi maggiori del SysV IPC riguarda la scelta di un unico ID per tutti i processi che, per correttezza, deve essere univoco e non dipendere dalla chiave di altri semafori relativi ad altri programmi che sono in esecuzione nel sistema: la ftok ( ), che utilizza due parametri (il percorso del file e un carattere, genera uno o più ID. Come procede la ftok: cerca l' "i-node", lo combina con il secondo parametro e genera l'ID.
E' bene non rimuovere il file onde evitare che chiamate successive della ftok generino una nuova, diversa da quella precedente.
Privacy |
Articolo informazione
Commentare questo articolo:Non sei registratoDevi essere registrato per commentare ISCRIVITI |
Copiare il codice nella pagina web del tuo sito. |
Copyright InfTub.com 2025