scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_prev.gif  scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_up.gif  scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_next.gif  scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_home.gif

Osztott memória (shared memory)

Alkalmazása esetén ugyanazt a memóriarészt használja az összes összeköttetésben levő folyamat...


 

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link.gif  Definíció

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link.gif  Műveletek az osztott memóriával

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gif  Létrehozás(shmget)

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gif  Az osztott memória adatainak lekérdezése, módosítása és törlése(shmctl)

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gif  Memóriarész hozzárendelése(shmat)

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gif  Memóriarész hozzárendelésének megszüntetése(shmdt)

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link.gif  Példa

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link.gif  Posix

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link.gif  Műveletek az osztott memóriával

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gifLétrehozás (shm_open())

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gifOsztott memória eltávolítása (shm_unlink());

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gifAdatok memóriába ágyazása (mmap())

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gifMemória felszabadítása (munmap())

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gifHozzáférés módosító (mprotect())

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_link.gifMéretre igazítás (ftruncate())

scription: Description: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link.gif Posix példa

 

 

 

           

 

 

 


 

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_link_p.gif  Szemaforok (semaphores)

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_book.gif  Definíció

Az osztott vagy közös memória segítségével megoldható, hogy két vagy több folyamat ugyanazt a memóriarészt használja. Az osztott memóriazónák általi kommunikáció elvei:

- Egy folyamat létrehoz egy közös memóriazónát. A folyamat azonosítója bekerül a memóriazónához rendelt struktúrába.

- A létrehozó folyamat hozzárendel az osztott memóriához egy numerikus kulcsot, amelyet minden ezt a memóriarészt használni kívánó folyamatnak ismernie kell. Ezt a memóriazónát az shmid változó azonosítja.

- A létrehozó folyamat leszögezi a többi folyamat hozzáférési jogait az illető zónához. Azért, hogy egy folyamat (beleértve a létrehozó folyamatot is) írni és olvasni tudjon a közös memóriarészből, hozzá kell rendelnie egy virtuális címterületet.

Ez a kommunikáció a leggyorsabb, hiszen az adatokat nem kell mozgatni a kliens és a szerver között.

A folyamatoknak a közös memóriarészhez való hozzáférését nem a rendszer felügyeli, a konfliktusok kezelése a felhasználó folyamatok feladata. Ha a szerver adatokat helyez el a közös memóriarészben, akkor a kliensnek várakoznia kell egészen a művelet befejezéséig, s csak akkor férhet hozzá az illető adatokhoz. A hozzáférések összehangolására gyakran használunk szemaforokat.

A rendszer minden egyes közös memóriarész esetén a következő adatokat tárolja:

struct shmid_ds
{
  struct ipc_perm shm_perm;
  /* definiálja a jogokat és a tulajdonost */
  struct anon_map *shm_amp;  /*
pointer a rendszerben*/
  int shm_segz;              /*
szegmens mérete bájtokban*/
  pid_t shm_cpid;            /*
létrehozó folyamat pid-je*/
  pid_t shm_lpid;            /*
utolsó shmop() pid-je*/
  ulong shm_nattach;         /*
eddig kapcsolódót folyamatokszáma*/
  ulong shm_cnattch;         /*
csak az shminfo használja*/
  time_t shm_atime;         /*
utolsó beírás ideje*/
  time_t shm_dtime;         /*
utolsó kiolvasás ideje*/
  time_t shm_ctime;          /*
utolsó struktúramódosítás ideje*/
}

Egy folyamat csak akkor férhet hozzá a közös memóriarészhez ha:

- a folyamat a superuser-é,

- a felhasználó ID-je (uid) megegyezik az shm_perm.cuid-vel vagy az shm_perm.uid-vel és az shm_perm.mode tartalmazza a kívánt jogokat,

- a felhasználó csoportazonosítója (gid) megegyezik az shm_perm.cgid vagy shm_perm.gid értékek egyikével és az shm_perm.mode tartalmazza a kívánt jogokat,

- a felhasználó beleesik a "többi felhsználó" kategóriába és az shm_perm.mode tartalmazza a megfelelő jogokat.

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_book.gif  Műveletek az osztott memóriával

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Létrehozás (shmget)

Az shmget rendszerfüggvény engedélyezi a közös memória azonosítójának lekérdezését felhasználva egy bizonyos kulcsot. Alakja:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, int size, int flg);

A függvény visszatérési értéke a key kulcshoz rendelt memóriazóna azonosítója, illetve -1 hiba esetén. A size változóban a közös memória méretét kell megadni, míg az flg-ben a létrehozási tevékenységet és a hozzáférési jogokat. A kulcsot a közös memóriát használó összes folyamatnak kell ismernie.

Egy új memóriaterület létrehozása esetén az flg mezőt a következő formában kell megadni:

IPC_CREAT  |  IPC_EXCL  |  hozzáférési_jogok

Ha az IPC_CREAT opció nincs beállítva, és már létezik egy előzőleg létrehozott memóriazóna, a függvény ennek az azonosítóját téríti vissza.

Példaként hozzunk létre egy 2003 kulccsal rendelkező 200 bájt méretű memóriarészt.

#define KEY 2003

int shmid;
shmid = shmget((key_t) KEY, 200, IPC_CREAT | 0666);

Ha egy már létező osztott memóriarész azonosítóját (ID-ját) szeretnénk meghatározni, akkor a size és az flg mezőbe 0-t írunk – ez esetben a függvény nem fog létrehozni új sort. Például az előzőleg létrehozott memóriazóna esetén a következőképpen járunk el:

shmid = shmget((key_t) KEY, 0, 0);

Létrehozáskor a társított adatstruktúra (shm_perm) mezői a következő információkkal töltődnek fel:

- shm_perm.cuid, shm_perm.uid– az shmget függvényt meghívó folyamathoz hozzárendelt felhasználó ID-ja,
-
shm_perm.cgid, shm_perm.uid– az shmget függvényt meghívó folyamathoz hozzárendelt felhasználócsoport ID-ja,
-
shm_perm.mode– az shmget függvény hívásakor megadott flg argumentum, amely a hozzáférési jogokat tartalmazza,
-
shm_qnum, shm_lspid, shm_lrpid, shm_stime, shm_rtime – értéke 0,
-
shm_ctime– az aktuális időt tartalmazza,
-
shm_segz– az shmget függvény hívásakor megadott size argumentum.

Előfordulhat, hogy egy osztott memóriazónának nincs hozzárendelt kulcsa. Ebben az esetben a key paraméternek az IPC_PRIVATE értéket adjuk.

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Az osztott memória adatainak lekérdezése, módosítása és törlése (shmctl)

Az shmctl függvény az osztott memóriarész információinak lekérdezésére, módosítására és törlésére használható. Szintaxisa:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

A függvény visszatérési értéke 0, ha a művelet sikeres volt, ellenkező esetben -1. Az shmid paraméter az shmget függvény által meghatározott osztott memóriarész azonosítója.

A cmd argumentum a kívánt műveletet határozza meg és a következő értékeket veheti fel:

- IPC_STATaz osztott memóriához rendelt struktúra tartalma a buf változóba kerül,

- IPC_SETaz osztott memóriához rendelt struktúrát frissíti a buf által megadott struktúrával,

- IPC_RMID – az osztott memóriarész elméletileg törlődik; a tulajdonképpeni törlésre csak akkor kerül sor, amikor az utolsó folyamat is, amely ezt a zónát használja, megszakítja a kapcsolatát ezzel a memóriarésszel; függetlenül attól, hogy ez a rész éppen használat alatt van-e vagy sem az ID törlődik, s ezáltal ez a memóriarész többet nem osztható ki egyetlen folyamat számára sem; ebben az esetbe a buf argumentumnak a NULL értéket kell adni,

- SHM_LOCK – megtiltja a közös memóriarész swappinggel történő kipakolását,

- SHM_UNLOCK – engedélyezi a közös memóriarész swappinggel történő kipakolását.

Példa:

#define KEY 2003

shmid = shmget((key_t) KEY, 0, 0);
shmctl(shmid, IPC_RMID, NULL);

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Memóriarész hozzárendelése (shmat)

Az shmat függvény feladata egy folyamat címterületéhez hozzárendelni egy osztott memóriazónát. A hozzárendelés után a folyamat írhat, illetve olvashat erről a memóriarészről. A függvény szintaxisa:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

void *shmat(int shmid, void *addr, int flg);

A függvény visszatérített értéke egy pointer a közös memóriazónára, ha a művelet sikeres volt, ellenkező esetben -1. Az shmid paraméter az shmget által meghatározott osztott memória azonosítója.

A addr pointer típusú változó a közös memóriarész hozzáférési címe a hívó folyamat adatszegmensében. Ezért ha:

- ha az addr NULL, a következő esetek fordulnak elő:

a. ha az SHM_RND opció be van állítva, a hozzárendelés az addr címhez történik,

b. ha az SHM_RND nincs beállítva, a hozzárendelés az (addr - (addr mod SHMLBA)) címhez történik,

- ha az addr = NULL, a memóriarész a rendszer által kiválasztott első szabad címhez történik (ajánlott).

Az flg paraméter meghatározza a hozzárendelt memória megadási módját (SHM_RND) és a közös részhez való hozzáférést, tehát hogy írásvédett (SHM_RDONLY) vagy sem.

A következő példa bemutatja, hogyan lehet írni egy közös memóriazónára:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

#define KEY 2003

void main(void)
{
  int shmid;
  char *p;
  ...
  shmid = shmget((key_t) KEY, 0, 0);
  p = shmat(shmid, NULL, 0);
  strcpy(p, "proba");
 
...
  exit(0);
}

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Memóriarész hozzárendelésének megszüntetése (shmdt)

Az shmdt függvény feladata a hívó folyamat címterületéhez hozzárendelt osztott memóriazóna felszabadása. Megjegyezzük, hogy a memóriarészhez hozzárendelt struktúra és az ID nem törlődik a rendszerből, míg egy folyamat (általában a szerver) az shmctl függvényhívással (IPC_RMID) azt végérvényesen nem törli. Alakja:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmdt(void *addr);

A következő programrészlet bemutatja, hogyan lehet kiolvasni adatokat egy olyan közös memóriazónából, ahová előzőleg egy másik folyamat írt. A végén a memóriaterületet felszabadítjuk és töröljük.

#include <stdio.h>
#include <sys/type.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define KEY 2003

void main(void)
{
  int shmid;
  char *p;
 
...
  shmid = shmget((key_t) KEY, 0, 0);
  p = shmat(shmid, NULL, 0);
  printf("a kozos memoria tartalma: %s\n", p);
  shmdt(p);
  shmctl(shmid, IPC_RMID, NULL);
  exit(0);
}

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_book.gif  Példa(Letöltés)

Készítsünk olyan programot, amely létrehozza, olvassa, írja és törli az osztott memóriát! A műveletet a parancssoron keresztül fogjuk megadni. Amennyiben egy művelet kiadásakor a közös memória nem létezik a program automatikusan hozza létre azt!

A folyamat tehát a következő műveleteket tudja elvégezni:

- írás a memóriazónába: shmtool w "text"
- a memóriazónán található szöveg kiolvasása:
shmtool r
- a hozzáférési jogok módosítása (mode):
shmtool m (mode)
- memóriarész törlése:
shmtool r

A forráskód tartalmazza a főprogramot és a műveleteket elvégző segédeljárásokat. (Az ftok utasítással a folyamat számára egyedi kulcsot hozunk létre.)

#include <stdlib.h>
#include <stdio.h>

#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SEGSIZE 100                                 /* a tárolandó szöveg max. mérete */

void writeshm(int shmid, char *segptr, char *text);
void readshm(int shmid, char *segptr);
void removeshm(int shmid);                          /*
függvények deklarálása*/
void changemode(int shmid, char *mode);
void usage(void);

int main(int argc, char *argv[])                    /* parancssorból a paraméterek*/
{
  key_t key;                                        /*
kulcs*/
  int shmid;                                        /*
osztott memória ID-ja*/
  char *segptr;                                     /*
osztott memória címe*/

  if (argc == 1)
    usage();                                        /*
hiányos paraméterlista*/

  key = ftok(".", 'S');                             /* egyedi kulcs létrehozása*/

                                                    /* megnyitás, szükség esetén létrehozás */

  if ((shmid = shmget(key, SEGSIZE, IPC_CREAT|IPC_EXCL|0666)) == -1)
  {
    printf("az osztott memoriazona letezik - megnyitom\n");

    if ((shmid = shmget(key, SEGSIZE, 0)) == -1)
    {
      perror("shmget hiba");
      exit(1);
    }
  }
  else
    printf("letrehozok egy uj osztott memoriazonat\n");

                                                    /* memóriacím hozzárendelése*/

  if ((segptr = shmat(shmid, 0, 0)) == (void *) -1)
  {
    perror("shmat hiba");
    exit(1);
  }

  switch (tolower(argv[1][0]))                      /* a param. alapján elvégzi a műv.*/
  {
    case 'w':                                       /*
megadott szöveg írása*/
      writeshm(shmid, segptr, argv[2]);
      break;
    case 'r':                                       /*
osztott memóriazóna kiolvasása*/
      readshm(shmid, segptr);
      break;
    case 'd':                                       /*
törlés*/
      removeshm(shmid);
      break;
    case 'm':                                       /*
jogok módosítása*/
      changemode(shmid, argv[2]);
      break;
    default:                                        /*
hibás opció*/
      usage();
  }
}

void writeshm(int shmid, char *segptr, char *text)
{
  strcpy(segptr, text);                             /*
szöveg beírása a memóriába */
  printf("kesz...\n");
}

void readshm(int shmid, char *segptr)
{
  printf("segptr: %s\n", segptr);                   /*
mem. tartalmának kiolvasása*/
}

void removeshm(int shmid)
{
  shmctl(shmid, IPC_RMID, 0);                       /*
osztott memória törlése*/
  printf("torolve\n");
}

void changemode(int shmid, char *mode)
{
  struct shmid_ds myshmds;
  shmctl(shmid, IPC_STAT, &myshmds);               /*
aktuális jogok lekérdezése*/
  printf("a regi jogok: %o\n", myshmds.shm_perm.mode);
  sscanf(mode, "%o", &myshmds.shm_perm.mode);
  shmctl(shmid, IPC_SET, &myshmds);                /*
új jogok beállítása*/
  printf("az uj jogok: %o\n", myshmds.shm_perm.mode);
}

void usage(void)                                   /* használati útmutató */
{
  printf("shmtool - osztott memoria menedzselo rendszer\n\n");
  printf("HASZNALAT: shmtool (w)rite <szoveg>\n");
  printf("                   (r)ead\n");
  printf("                   (d)elete\n");
  printf("                   (m)ode change <oktalis_mod>\n");
  exit(1);
}

Makefile(Fedora disztribúció):

 

shmtool: shmtool.c

  gcc shmtool.c -o shmtool

 

A fenti példa tesztelésekor a következő eredményre jutottunk:

$ shmtool w teszt
letrehozok egy uj osztott memoriazonat
kesz...

$ shmtool r
az osztott memoriazona letezik - megnyitom
segptr: teszt

$ shmtool d
az osztott memoriazona letezik - megnyitom
torolve

$ shmtool w szasz
letrehozok egy uj osztott memoriazonat
kesz...

$ shmtool r
az osztott memoriazona letezik - megnyitom
segptr: szasz

$ shmtool d
az osztott memoriazona letezik - megnyitom
torolve

$ shmtool m 660
letrehozok egy uj osztott memoriazonat
a regi jogok: 666
az uj jogok: 660

$

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_book.gifPOSIX-kiegészítés

A POSIX osztott memória lehetővé teszi a folyamatok számára a kommunikációt a memória bizonyos részeinek a megosztásával.
A UNIX operációs rendszer újabb változatai lehetőséget adnak a fájlok memórián keresztül történő elérésére a fájlnak a memóriába ágyazásával
(ezzel lehetőség nyílik a fájl tartalmának memóriaműveletek segítségével történő módosítására, amely gyakran hatékonyabb a hagyományos read() illetve write() rendszerhívásoknál.)

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_book.gifMűveletek osztott memóriával

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Létrehozás (shm_open())

Megnyitja / létrehozza az osztott memóriát.

Szintaxis

#include <fcntl.h>
#include <sys/mman.h>
int shm_open( const char *name,
              int oflag,
              mode_t mode );

Leírás:

Az shm_open() rendszerfüggvény visszatéríti a name által jelölt memória objektumhoz társított fájl deszkriptort.
Az osztott memória egészen addig fog létezni, amíg a rendszer le nem áll, vagy az összes folyamat be nem zárja (unmap) és amíg az utolsó folyamat meg nem hívja a törlést (
shm_unlink()).

Flagek:

<fcntl.h> által definiált flagek:

O_RDONLY              //Read only

    O_RDWR                  // írásra és olvasásra
                O_CREAT                 // Amennyiben az osztott memória létezik és az O_EXCL nincs beállítva, nem történik semmi. Különben

                                           az osztott memóriát létrehozza a mode által jelölt jogosultságokkal.

O_EXCL                    // HA az O_CREAT és az O_EXCL be van állítva, az shm_open() hibával tér vissza, amennyiben az osztott memória létezik.
O_TRUNC                // ha az osztott memória objektum létezik és sikeresen meg volt nyitva O_RDWR módban, akkor a hosszát átállítja 0-ra és a

                                       tulajdonos változatlan marad

 

A jogosultság bitek beállítása a mode értéke alapján történik

<sys/stat.h> által definiált szimbolikus konstanstok

                                    Tulajdonosra vonatkozóan

                                                S_IRWXU      írás, olvasás, végrehajtás

                                                S_IRUSR      olvasás

                                                S_IWUSR      írás

                                                S_IXUSR       végrehajtás

                                    Csoport:

                                                S_IRWXG      írás, olvasás, végrehajtás

                                                S_IRGRP      olvasás

                                                S_IWGRP      írás

                                                S_IXGRP       végrehajtás

                                    Többiek:

                                                S_IRWXO      írás, olvasás, végrehajtás

                                                S_IROTH       olvasás

                                                S_IWOTH      írás

                                                S_IXOTH       végrehajtás

Példa:

int shmfd;    

        shmfd = shm_open(SHMOBJ_PATH, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG); 

        if (shmfd < 0) {

              perror("In shm_open()");

                    exit(1);

        }

Eredmény:

A fájl deszkriptora, ha sikereses volt a létrehozás, különben -1 és beállítja az errn-ot

 

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Osztott memória eltávolítása (shm_unlink());

Szintaxis:

#include <sys/mman.h>
int shm_unlink( const char *name );

Az shm_unlink() hasonlít az unlink()-hez, lekapcsolódik az osztott memória objektumról,  majd ha minden folyamat lekapcsolódott, felszabadítja a memóriát es ezáltal az osztott memóriában tárolt adatok elvesznek

Példa:
  if (shm_unlink(SHMOBJ_PATH) != 0) {
        perror("In shm_unlink()");

               
exit(1);
  }

 

Eredmény:

    0: sikeres
    -1: sikertelen és errno-t beállítja

 

scription: Description: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif  Adatok memóriába ágyazása(mmap())

Szintaxis:

#include <sys/mman.h>
caddr_t mmap( caddr_t addr,
              size_t len,
              int prot,
              int flags,
              int fd,
              off_t offset);

Paraméterek:

Az mmap() rendszerhívás első paramétere caddr_t típusú (az ilyen típusú változók egy tetszőleges memóriacímet kaphatnak értékül, általában char * típussal implementálják). Az első argumentumban azt a memóriacímet kell megadnunk, ahova be akarjuk ágyazni a kérdéses fájlt (vagy annak egy részét). A programok hordozhatósága érdekében itt 0-t adjunk meg, ugyanis ekkor az operációs rendszer maga választ egy szabad memóriaterületet, ahova a fájlt beágyazza. Sikeres végrehajtás esetén az mmap() rendszerhívás az fd argumentumban kijelölt fájldeszkriptorú fájl offset argumentumában adott pozíciótól kezdődő len argumentumban bájtokban megadott hosszú részét beágyazza, és a rendszerhívás visszatérési értéke a beágyazott fájl-rész memóriabeli kezdőcíme (a beágyazás kezdőcíme).

A prot paramétert a <sys/mman.h> header allományban tárolt szimbolikus konstansok bitenkénti VAGY művelettel képzett összekapcsolásával állíthatjuk elő aszerint, hogy a beágyazott fájl-részen milyen műveleteket akarunk megengedni. Ha egy fájlra nincs írás-engedélyünk a hozzárendelt rwx-bitek alapján, akkor a memóriába ágyazással sem módosíthatjuk azt.

<sys/mman.h> által definiált szimbolikus konstansok:
    PROT_EXEC            //végrehajtható
    PROT_NOCACHE   //kikapcsolja a "cache" mechanizmust
    PROT_NONE           //elérhetetlené teszi
    PROT_READ            //olvasható
    PROT_WRITE          //
írható

Flagek:

MAP_PRIVATE         // fájlon végzett módosítások ideiglenesek, azaz az eredeti fájlon nem jelennek meg, a fájl többi felhasználója nem látja azokat
MAP_SHARED
MAP_FIXED //Pontosan értelmezi az addr paramétert

Példa:

  shared_msg = (struct msg_s *)mmap(NULL, shared_seg_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);

  if (shared_msg == NULL) {

        perror("In mmap()");

        exit(1);

  }   

scription: Description: Description: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif Memória felszabadítása(munmap())

Szintaxis:

#include <sys/mman.h>
int munmap( void *addr, size_t len );

Eltávolítja az addr címtől kezdve, len byteon keresztül a mmap által a memóriához való hozzárendeléseket. Amennyiben az adott tartományban nem volt a memóriához rendelve semmi, az munmap() nem csinál semmit.

Példa:

    if (munmap(shared_msg,shared_seg_size)==-1){

        perror("munmap:");

    }

 

Eredmény:

    0: sikeres
    -1: sikertelen és errno-t beállítja

scription: Description: Description: Description: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif Hozzáférés módosító(mprotect())

Szintatxis:

#include <sys/mman.h>
int mprotect( void *addr,
              size_t len,
              int prot );

Beállítja a memóriához való hozzáférést addr címtől kezdődően, len byteon keresztül. Prot határozza meg a hozzáférés módosítót(mmap()  függvénynél leírt szimbolikus konstansok).

Példa:

    if (mprotect(shared_msg,shared_seg_size, PROT_NONE)==-1){

        perror("mprotect");

    }

 

Eredmény:

    0: sikeres
    -1: sikertelen és errno-t beállítja

scription: Description: Description: Description: Description: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\g_book.gif Méretre igazítás (ftruncate())

Szintaxis:

#include <unistd.h>
#include <sys/types.h>
int ftruncate(int fd, off_t length)

fd deszkriptorú fájlt length méretre alakítja. Ha eredetileg hosszabb volt, levágja a végét ( elvesztődik ), ha pedig rövidebb volt, kibővíti és az új rész \0-t fog tartalmazni.

Példa:
  if (ftruncate(shmfd, shared_seg_size)==1)
  {
        perror("ftruncate:");
  }

Eredmény:

    0: sikeres
    -1: sikertelen és errno-t beállítja

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\n_book.gif  Példa(Letöltés)

Server:    Létrehozza az osztott memóriát, beleír egy msg_s típusú struktúrát ( tartalmát véletlenszerűen generálja), majd várakozik egészen addig amíg a 
                kliens át nem írja a típust -1 re. Ha a kliens átírta a típust -1 re, törli az osztott memóriát és kilép.

Client:     Csatlakozik az osztott memóriára, kiolvassa a tartalmát majd a típust átírja -1 re 

server.c:

#include <stdio.h>
#include <sys/mman.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <stdlib.h>

#include <time.h>

 

#define SHMOBJ_PATH         "/example"

#define MAX_MSG_LENGTH      50

#define TYPES               8  

 

/* üzenet struktúra */

struct msg_s {

    int type;

    char content[MAX_MSG_LENGTH];

};

 

int main(int argc, char *argv[]) {

    int shmfd;

    int shared_seg_size = (sizeof(struct msg_s));   /* megosztott szegmens mérete (jelen esetben egyetlen struktúrát fogunk megosztani)*/

    struct msg_s *shared_msg;                   

   

    shmfd = shm_open(SHMOBJ_PATH, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG);  /* memória objektum létrehozása */

    if (shmfd < 0) {

        perror("In shm_open()");

        exit(1);

    }

    printf("Created shared memory object %s\n", SHMOBJ_PATH);

   

    ftruncate(shmfd, shared_seg_size);            /* méret beállítása, hogy férjen el az egész struktúra */

 

                                            /* struktúra megosztása */   

    shared_msg = (struct msg_s *)mmap(NULL, shared_seg_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);

    if (shared_msg == NULL) {

        perror("In mmap()");

        exit(1);

    }

    printf("Shared memory segment allocated correctly (%d bytes).\n", shared_seg_size);

 

    srandom(time(NULL));

    shared_msg->type = random() % TYPES;    /* osztott memória tartalmának megváltoztatása */

    int tmp = shared_msg->type;

    snprintf(shared_msg->content, MAX_MSG_LENGTH, "My message, type %d, num %ld", shared_msg->type, random());

 

    printf("waiting...\n");

 

/* várakozás amíg a kliens át nem írja a típust -1 re. A foglalva várakozás nem a legjobb megoldás, de jelen esetben az egyszerűség kedvéért ez is megfelel */

    while (shared_msg->type==tmp) { };

 

    printf("type = %d\n ",shared_msg->type);     

 

    if (munmap(shared_msg,shared_seg_size)==-1){

        perror("munmap:");

                exit(1);

    }

    printf("Munmap: succes\nclose\n");

 

    if (shm_unlink(SHMOBJ_PATH) != 0) {   /* lekapcsolódás az osztott memóriáról*/

        perror("In shm_unlink()");

        exit(1);

    }

    return 0;

}

 

client.c:

#include <stdio.h>

#include <unistd.h>

#include <sys/mman.h>

#include <sys/types.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <stdlib.h>

#include <time.h>

 

#define SHMOBJ_PATH         "/example"     

#define MAX_MSG_LENGTH      50

#define TYPES               8

 

/* üzenet struktúra */

struct msg_s {

    int type;

    char content[MAX_MSG_LENGTH];

};

 

int main(int argc, char *argv[]) {

    int shmfd;

    int shared_seg_size = (sizeof(struct msg_s));   /* megosztott szegmens mérete (jelen esetben egyetlen struktúrát fogunk megosztani)*/

    struct msg_s *shared_msg;    

 

    shmfd = shm_open(SHMOBJ_PATH, O_RDWR, S_IRWXU | S_IRWXG);  /* memória objektum megnyitása*/

    if (shmfd < 0) {

        perror("In shm_open()");

        exit(1);

    }

    printf("Connecting to the shared memory object %s\n", SHMOBJ_PATH);

   

                                            /* struktúra betöltése */   

    shared_msg = (struct msg_s *)mmap(NULL, shared_seg_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);

    if (shared_msg == NULL) {

        perror("In mmap()");

        exit(1);

    }

 

    printf("Message type is %d, content is: %s\n", shared_msg->type, shared_msg->content);

 

    shared_msg->type = -1;

 

    return 0;

}

 

Makefile(Fedora disztribúció):

SRC1     = server.c

SRC2     = client.c

OBJ1     = $(SRC1:.c=.o)

OBJ2     = $(SRC2:.c=.o)

CFLAGS   = -Wall -pedantic --ansi -D_GNU_SOURCE -std=gnu99

INCLUDES = -I./

LIBS     = -lrt

LIBPATH  =

DEP_FILE = .depend

SNDR     = s

RCVR     = kl

 

.PHONY: all clean distclean

 

all: depend $(SNDR) $(RCVR)

 

$(SNDR): $(OBJ1)

  @echo Makefile - linking $@

  @$(CC) $(LIBPATH) $(LIBS) $^ -o $@

 

$(RCVR): $(OBJ2)

  @echo Makefile - linking $@

  @$(CC) $(LIBPATH) $(LIBS) $^ -o $@

 

.c.o:

  @echo Makefile - compiling $<

  @$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

 

clean:

  $(RM) $(OBJ1) $(OBJ2)

 

distclean: clean

  $(RM) $(SNDR) $(RCVR)

  $(RM) $(DEP_FILE)

 

depend: $(DEP_FILE)

  @touch $(DEP_FILE)

 

$(DEP_FILE):

  @echo Makefile - building dependencies in: $@

  @$(CC) -E -MM $(CFLAGS) $(INCLUDES) $(SRC1) >> $(DEP_FILE)

  @$(CC) -E -MM $(CFLAGS) $(INCLUDES) $(SRC2) >> $(DEP_FILE)

 

ifeq (,$(findstring clean,$(MAKECMDGOALS)))

ifeq (,$(findstring distclean,$(MAKECMDGOALS)))

-include $(DEP_FILE)

endif

endif

 

Kimenet:

  Server.c:

$ ./s
Created shared memory object /example
Shared memory segment allocated correctly (56 bytes).
waiting...
type = -1
Munmap: succes
close
$

Client.c:

$ ./kl
Connecting to the shared memory object /example
Message type is 6, content is: My message, type 6, num 207394245
$

 


Copyright (C) Buzogány László, 2002

scription: Description: Description: Description: Description: C:\Users\ReB\Desktop\Folyamatok\simple.gif

About