C Programmazione

Memoria condivisa POSIX con programmazione C

Memoria condivisa POSIX con programmazione C
La memoria condivisa POSIX è un framework per la comunicazione tra processi (IPC) specificato nelle specifiche POSIX. Due (o più) attività possono leggere da esso e scrivere nella zona di memoria condivisa mentre stabiliscono la memoria condivisa. La memoria condivisa POSIX non impone sempre gli esborsi di copia, a differenza di altre strutture IPC (e.g., tubo, presa, ecc.), ed è auspicabile per alcuni programmi.

Chiamate in memoria condivisa POSIX

Le funzioni di memoria condivisa POSIX si concentrano sul concetto UNIX che l'oggetto deve essere un documento quando si eseguono attività di input/output su un'entità. Pertanto, poiché reciti e iscrivi a un'entità di memoria POSIX reciproca, quest'ultima deve essere considerata come un documento. Un documento mappato in memoria è un'entità di memoria condivisa POSIX. Per usare il shm_open funzione di chiamata di sistema sotto /dev/shm, vengono generati documenti di memoria condivisa separati. Ci sono solo due chiamate di sistema di memoria condivisa dedicate da POSIX, shm_open, e shm_unlink, che sono strettamente correlati all'apertura e allo scollegamento delle chiamate del file system. Il ftruncate, mmap, e munmap le chiamate del framework per i documenti vengono utilizzate per eseguire altre attività sulla memoria condivisa POSIX. È necessario collegare un programma che utilizza chiamate di memoria condivisa POSIX a -lrt.

I programmi che utilizzano chiamate di memoria condivisa POSIX devono seguire i seguenti passaggi:

Usando shm_apri(), formare un oggetto di memoria condivisa. Il descrittore del documento può essere ripristinato se la formazione dell'oggetto ha successo.

Con ftruncate(), la dimensione dell'oggetto sarà fissa.

Con carta geografica() e MAP_CONDIVISO, delinea questo oggetto nello spazio degli indirizzi presente.

Leggere/scrivere la memoria condivisa.

attraverso mappa comune(), non delineare la memoria condivisa.

Uso vicino() chiudere l'oggetto.

Attraverso shm_unlink(), eliminare l'oggetto nella memoria condivisa.

shm_apri()

Come descritto sopra, shm_apri() è usato per generare un nuovo oggetto di memoria condivisa. Rende l'oggetto accessibile alla procedura chiamante utilizzando il descrittore invertito. La seguente è la definizione di questa chiamata di funzione:

>> Int shm_open( const char *name, int oflag, mode_t mode);

Il primo parametro è il nome dell'oggetto di memoria condivisa. È una stringa con terminazione null di /nome tipo, con la clausola che nessun altro carattere può essere una barra diversa dal suo primo carattere. Oflag è un piccolo velo creato con molti dei flag precedenti da OR-ing, sia via O_RDONLY o O_RDWR. I parametri descritti indicano che il suo oggetto di memoria condivisa deve essere formato (O_CREAT) quando non esiste già e anche l'oggetto è disponibile per la lettura e la scrittura (O_RDWR). L'ultimo argomento imposta le approvazioni della directory per l'oggetto di memoria condivisa.

shm_unlink()

Shm_unlink() elimina l'entità di memoria condivisa POSIX che è stata precedentemente sviluppata. Il descrittore di documento intero per l'oggetto di memoria condivisa viene restituito tramite una chiamata efficace a shm_apri(). Come definito sotto il shm_apri(), il nome del parametro è il titolo dell'entità di memoria condivisa. Quella che segue è la definizione di the shm_unlink() funzione:

>> Int shm_unlink( const char *nome);

frugare()

Dopo aver impostato l'oggetto, il frugare() il metodo viene scartato per impostare la dimensione dell'entità in byte. La definizione della funzione è la seguente:

>> Int ftruncate( int fd, off_t lunghezza);

Quando si costruisce una memoria POSIX condivisa, la capacità è effettivamente pari a zero byte. È possibile eseguire il rendering dell'entità di memoria condivisa POSIX con byte di lunghezza di dimensione tramite frugare. troncare rende zero all'esecuzione. troncare uscite -1 in caso di guasto e errno è impostato per attivare l'errore.

mmp()

Alla fine, un documento mappato in memoria con l'entità di memoria condivisa viene impostato tramite il mmp() metodo. Quindi, produce un puntatore di documento mappato in memoria che viene scartato per raggiungere l'entità di memoria condivisa. Quella che segue è la definizione di the mmp() funzione:

>> Void *mmap ( void *addr, size_t length, int prot, int flags, int fd, off_t offset);

In questo, 'addr' è l'indirizzo a cui verrà mappato. La 'lunghezza' è l'intervallo dell'entità di memoria condivisa. I valori per prot possono differire, ma useremo il PROT READ | SCRIVI PROT. Ci sono diversi flag, ma MAP SHARED è essenziale per la memoria condivisa. Ora, 'fd' è un descrittore di documento ottenuto in precedenza. L'offset è il punto in cui inizia la mappatura nell'entità di memoria condivisa; è possibile utilizzare anche il valore di offset 0. Al termine, mmp() restituisce il puntatore alla posizione di mappatura dell'entità di memoria condivisa.

mappa comune()

Nella posizione indicata da addr e ottenendo size, length, munmap annulla la mappatura dell'elemento della memoria condivisa. munmap restituisce 0 al completamento e -1 nella situazione di imprecisione, nel qual caso viene assegnato errno per attivare l'errore.

>> Void munmap ( void *addr, size_t length);

Esempio: mittente e destinatario

Prendiamo l'esempio del mittente e del destinatario. Il mittente creerà un nuovo oggetto di memoria condivisa con il nome /shmem-esempio e inscrivere tre numeri nella memoria condivisa attraverso di essa. Ora, il destinatario può esporre l'oggetto della memoria condivisa e recitare i tre numeri dalla memoria. Creeremo tre file con i nomi protocollo.h, mittente.c, e ricevitore.c.

$ protocollo touch.h
$ tocca il mittente.c
$ touch ricevitore.c

Successivamente, aggiungeremo il codice sorgente seguente al "protocollo" dei file.h,"mittente.c,' e 'ricevitore.c.'Ora, salveremo tutti e li chiuderemo.

Ora compileremo e uniremo il codice sopra usando la parola chiave -lrt separatamente per il mittente.c e ricevitore.c file. Ecco il comando per farlo:

$ gcc -o mittente mittente.c -lrt
$ gcc -o ricevitore ricevitore.c -lrt

Ora eseguiremo il codice del mittente utilizzando il seguente comando. L'output è riportato di seguito.

$ ./mittente

Eseguendo il codice del mittente, l'oggetto di memoria condivisa è stato generato e può essere trovato sotto /dev/shm usando il comando qui sotto:

$ ls -l /dev/shm | grep shmem-esempio

Quando eseguiamo il codice del ricevitore, otterremo l'output seguente:

$ ./ricevitore

Ogni volta che la funzione gm_unlink() viene chiamato usando il file 'receiver.c,' l'oggetto /dev/shm/shmem-esempio sarà distaccato. In questo caso, non otterrai alcun oggetto in uscita, come mostrato di seguito.

$ ls -l /dev/shm/shmem-esempio

Conclusione

In questo articolo, hai imparato come utilizzare la memoria condivisa POSIX con la programmazione C in Ubuntu 20.04, inclusa ogni chiamata di funzione utilizzata per stabilire la memoria condivisa. Spero che questo articolo ti abbia aiutato a migliorare le tue conoscenze di programmazione e abbia coperto ogni dubbio che hai su questo argomento.

Come acquisire e riprodurre in streaming la tua sessione di gioco su Linux
In passato, giocare era considerato solo un hobby, ma con il tempo l'industria dei giochi ha visto una crescita enorme in termini di tecnologia e nume...
I migliori giochi da giocare con il tracciamento delle mani
Oculus Quest ha recentemente introdotto la grande idea del tracciamento manuale senza controller. Con un numero sempre crescente di giochi e attività ...
Come mostrare l'overlay OSD in app e giochi Linux a schermo intero
Giocare a giochi a schermo intero o utilizzare app in modalità a schermo intero senza distrazioni può tagliarti fuori dalle informazioni di sistema ri...