Deljenom memorijom se definiše oblast (segment) memorije koja se mapira i deli između više procesa. Ovo je najbrži oblik IPC zato što nema posrednika. Informacije se mapiraju direktno iz memorijskog segmenta u adresni prostor pozivajućeg procesa. Segment kreira jedan proces, a više procesa mogu da čitaju i pišu iz njega. Jezgro OS održava specijalnu internu strukturu za svaki segment deljene memorije koji postoji u njegovom adresnom prostoru (linux/shm.h)
struct shmid_ds
{
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */
time_t shm_atime; /* last attach time */
time_t shm_dtime; /* last detach time */
time_t shm_ctime; /* last change time */
unsigned short shm_cpid; /* pid of creator */
unsigned short shm_lpid; /* pid of last operator */
short shm_nattch; /* no. of current attaches */
unsigned short shm_npages; /* size of segment (pages) */
unsigned long *shm_pages; /* array of ptrs to frames ‐> SHMMAX */
struct vm_area_struct *attaches; /* descriptors for attaches */
};
Alocira segment deljene memorije.
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
Ako je uspešno izvedeno alociranje povratna vrednost je identifikator ka segmentu memorije, a ako nije -1 i postavlja errno na vrednosti:
Primer:
int open_segment(key_t keyval, int segsize)
{
int shmid;
if((shmid=shmget(keyval,segsize,IPC_CREAT|0660)) == ‐1)
return ‐1;
return shmid;
}
Izvršava operaciju kontrole definisanu sa cmd parametrom nad segmentom deljene memorije čiji je identifikator definisan sa shmid parametrom.
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
Povratna vrednost je 0 ako je operacija uspešno izvedena ili -1 ako nije i errno prima vrednosti:
Vrednosti parametra cmd mogu biti:
Kači memorijski segment identifikovan sa shmid u adresni prostor pozivajućeg procesa.
#include <sys/ipc.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
Ako je argument shmaddr 0 (NULL), jezgro OS pokušava da nađe nemapirani region. Ovakav način je preporučljiv. Adresa može biti definisana, ali se takav način uglavnom koristi samo za vlasnički hardver ili da bi se razrešili konflikti sa drugim aplikacijama.
Povratna vrednost je adresa na kojoj je segment prikačen za proces ili -1 i errno:
Primer:
char *attach_segment( int shmid)
{
return (shmat(shmid,0,0));
}
Odvaja segment deljenje memorije lociran na adresi definisanoj sa shmaddr od adresnog prostora pozivajućeg procesa. Segment koji treba da se odvaja mora prethodno biti prikačen pozivom shmat(). Parametar shmaddr je povratna vrednost sistemskog poziva shmat().
#include <sys/ipc.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
Ovim pozivom se ne uklanjanje segment iz jezgra OS. Nakon uspešnog odvajanja shm_nattch član strukture shmid_ds se smanjuje za jedan. Kada vrednost postane 0 jezgro fizički uklanja segment.
Ako je uspešno izvedeno povratna vrednost je 0, a ako nije -1 i errno:
Program radi jednu od dve stari:
/* shmdemo.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_SIZE 1024
int main(int argc, char *argv[])
{
key_t key;
int shmid;
char *data;
int mode;
if (argc > 2)
{
fprintf(stderr, "usage: shmdemo [data_to_write]\n");
exit(1);
}
/* pravi kljuc */
if ((key = ftok("shmdemo.c", 'R')) == -1)
{
perror("ftok");
exit(1);
}
/* povezuje se (i ako je moguce kreira) segment */
if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1)
{
perror("shmget");
exit(1);
}
/* prikaci segment da bi dobio pokazivac na njega */
data = shmat(shmid, (void *)0, 0);
if (data == (char *)(-1))
{
perror("shmat");
exit(1);
}
/* citaj ili modifikuj segment, na osnovu argumenta komandne linije */
if (argc == 2)
{
printf("writing to segment: \"%s\"\n", argv[1]);
strncpy(data, argv[1], SHM_SIZE);
}
else
printf("segment contains: \"%s\"\n", data);
/* odvaja se od segmenta */
if (shmdt(data) == -1)
{
perror("shmdt");
exit(1);
}
return 0;
}
Program iz primera pristupa deljenoj memoriji bez upotrebe semafora. Zašto je to opasno?