IPC: Zone de memorie comunca

Zonele de memorie comună reprezintă cel mai rapid mecanism de comunicare între procese pus la dispoziţie de pachetul IPC. Principiul de funcţionare este simplu: un proces construieşte o zonă de memorie la care se pot conecta 2 sau mai multe procese – acestea pot să scrie şi să citească date în \ din zona de memorie.

Este responsabilitatea programatorului să asigure consistenţa datelor din zona de memorie prin implementarea unui mecanism de excludere mutuală între procesele care doresc să accese simultan zona de memorie. Desigur nu apar probleme atunci când două procese încearcă să citească în mod concurent zona de memorie, ci problema apare atunci când un proces scrie un set de date şi un alt proces citeşte conţinutul zonei de memorie.

Pentru sincronizarea accesului la zona de memorie comună, se vor folosi semafoarele din pachetul IPC.

Construirea unei zone de memorie

Pentru a construi o zonă de memorie sau pentru a obţine id-ul unei zone de memorie existente se foloseşte funcţia sistem shmget. Semnătura funcţiei este:

     #include <sys/types.h>
     #include <sys/ipc.h>
     #include <sys/shm.h>
 
     int
     shmget(key_t key, int size, int shmflg);

Pagina man asociată funcţiei shmget este aceasta.

Argumentul size specifică dimensiunea în octeţi a zonei de memorie comună ce va creată. Argumentul shmflg are aceiaşi semnificaţie ca şi în cazul cozilor de mesaje.

Alocarea unei zone de memorie de 1024 octeţi se face astfel:

    int shm_id;
    shm_id = shmget(100, 1024

Pentru a putea utiliza o zonă de memorie (pentru a scrie şi citi date) un proces trebuie să îşi ataşeze zona de memorie la propria sa zonă de memorie.

Ataşarea zonei de memorie la propria zonă de memorie de către un proces se face folosind funcţia shmat. Semnătura funcţiei este:

     #include <sys/types.h>
     #include <sys/ipc.h>
     #include <sys/shm.h>
 
     void *
     shmat(int shmid, void *shmaddr, int shmflg);
 
     int
     shmdt(void *shmaddr);

Pagina man asociată funcţiei este aceasta .

Funcţia shmat returnează adresa de început a zonei de memorie comuncă. Argumentul shmaddr reprezintă adresa din zona de memorie a procesului unde funcţia shmat să încerce să mapeze zona de memorie comună – dacă acest argument este 0 se va selecta automat o adresă disponibilă. Argumentul shmflg permite setarea flag-ului SHM_RDONLY ce ataşează zona de memorie în mod citire exclusivă (nu se permite scrierea în zona de memorie comună).

Un exemplu de utilizare al funcţiei shmat este:

    char* shm_addr;
    /* attach the given shared memory segment, at some free position */
    shm_addr = shmat(shm_id, NULL, 0);

După ce un proces a terminat de utilizat o zonă de memorie aceasta trebuie detaşata de la procesul curent folosind funcţia shmdt (semnătura acesteia a fost prezentată mai sus împreună cu funcţia shmat).

Scrierea intr-o zona de memorie

După ce un proces şi-a ataşat o zonă de memorie şi a obţinut adresa de început a acesteia, datele pot fi scrise şi citite în \ din zona de memorie comună. În cadrul zonei de memorie pot fi scrise orice tip de date (cu excepţia pointerilor – care sunt la rândul lor nişte adrese).

În continuare este dat un scurt exemplu despre modul cum datele pot fi scrise într-o zonă de memotie comună. Practic se poate folosi orice metodă cunoscută în C pentru a scrie date la o adresă cunoscută.

    int shmid; 
    char *adr_zona; 
    ... 
    shmid=shmget(123, 0, 0); 
    adr_zona=shmat( shmid, NULL, 0); 
    strcpy( adr_zona, "SCRIE"); 
    ...

Citirea dintr-o zona de memorie

Pentru a citi date dintr-o zonă de memorie comună, procesul trebuie sa aibă ataşată zona de memorie la propria sa zonă de memorie şi apoi se poate folosi orice metodă cunoscută pentru citi date de la o adresă.

Alte operatii cu asupra zonelor de memorie

Funcţia de sistem shmctl are rolul de a efectua asupra zonei de memorie diverse operaţii: obţinerea de informaţii despre structură, modificarea informaţiilor structurii şi ştergerea structurii. Semnătura funcţiei shmctl este:

     #include <sys/types.h>
     #include <sys/ipc.h>
     #include <sys/msg.h>
 
     int
     shmctl(int shmid, int cmd, struct shmid_ds *buf);

Pagina man asociată funcţiei msgctl este aceasta.

Stergerea zonei de memorie folosind functia shmctl se face asfel:

      shmctl(shmid,IPC_RMID,0);