Hlavní navigace

Programování pod Linuxem pro všechny (21)

Jakub Matys 25. 6. 2004

Dnes začneme novou kapitolu, a to komunikace mezi procesy. Budeme se zabývat sdílenou pamětí, která, jak již název napovídá, umožňuje sdílet určitý pamětový segment mezi více procesy.

Sdílená paměť

Sdílená pamět je jedním z nejjednoduších řešení komunikace mezi procesy. Umožňuje dvěma nebo více procesům sdílet tutéž paměť tak, jako by ji mohly alokovat voláním funkce malloc(). Když jeden proces změní paměť, je tato změna viditelná i pro ostatní procesy.

Sdílená paměť představuje nejrychlejší prostředek pro komunikaci mezi procesy, protože všechny procesy sdílejí tutéž část paměti. Přístup do této paměti je stejně rychlý jako přístup do nesdílené paměti. Protože jádro nesynchronizuje přístup do sdílené paměti, musíte synchronizaci realizovat sami. Nejelegantnějším řešením se jeví řízení pomocí semaforů (příští díl).

Aby bylo možné používat nějaký segment paměti jako sdílený, musí jej jeden proces alokovat. Pak musí každý proces používající tuto paměť získat přístup připojením k paměťovému segmentu. Po skončení používání paměťového segmentu musí každý proces paměť odpojit. Jeden z procesů musí nakonec paměť dealokovat.

Alokace

Alokaci sdíleného paměťového segmentu může proces provést pomocí funkce shmget() (SHared Memory GET). Prvním parametrem funkce je celočíselný klíč specifikující segment, který se má vytvořit. Nespřízněné procesy mohou vytvořit tentýž sdílený segment použitím téže hodnoty klíče. Použití speciální konstanty IPC_PRIVATE jako hodnoty klíče garantuje, že bude vytvořen nový segment paměti (tj. nebudete alokovat sdílenou pamět jiného procesu).

Druhý parametr funkce specifikuje počet bytů v segmentu. Protože jsou segmenty alokovány pomocí stránek, počet skutečně alokovaných bytů je zaokrouhlen na celočíselný násobek velikosti stránky (velikost stránky získáte pomocí funkce getpagesize()).

Třetí parametr specifikuje volby funkce shmget(). V parametru se nastavují bity a může mít tyto hodnoty:

  • IPC_CREAT – bude vytvořen nový segment paměti.
  • IPC_EXCL – nevytvoří se nový segment, pokud se použije již existující klíč. Tak se zajistí pro volající procesy, že budou přistupovat k výlučnému segmentu. Když druhý parametr není definován a použije se existující segment, funkce shmget() vrátí existující segment a nevytvoří nový.
  • Mód – tato hodnota je tvořena devíti bity indikujícími přístupová práva k segmentu pro vlastníka, skupinu a ostatní uživatele. Přístupová práva se snadno specifikují pomocí konstant definovaných v sys/stat.h.

Např.:

int segment_id = shmget(shm_key, getpagesize(), IPC_CREAT | S_IRUSR | S_IWUSR); 

Pokud je volání úspěšné, funkce vrátí identifikátor segmentu. Jestliže segment sdílené paměti již existuje, provede se kontrola přístupových práv a také se zkontroluje, zda není segment označen pro destrukci.

Připojení a odpojení

Pomocí funkce shmat()(SHared Memory ATtach) si může každý proces sdílený paměťový segment zpřístupnit. Funkci se předává identifikátor paměťového segmentu SHMID vrácený funkcí shmget(). Druhým argumentem je ukazatel, který specifikuje, kde ve vašem adresovém prostoru chcete mapovat sdílenou paměť. Použijete-li hodnotu NULL, systém vybere nějakou dostupnou adresu. Třetím argumentem je příznak, který může obsahovat následující informace:

  • SHM_RND – indikuje, že adresy specifikované pro druhý parametr by měly být zaokrouhleny směrem dolů na násobek velikosti stránky.
  • SHM_RDONLY – indikuje, že segment bude určen pouze pro čtení.

Pokud volání funkce skončí úspěšně, vrátí funkce adresu připojeného sdíleného segmentu. Podřízené procesy automaticky sdílejí připojené paměťové segmenty (odpojit je mohou dle potřeby).

Odpojení sdíleného paměťového segmentu je realizováno pomocí funkce shmdt()(SHared Memory DeTach). Jejím argumentem je adresa vrácená funkcí shmat().

Řízení a dealokace sdílené paměti

Funkce shmctl() (SHared Memory ConTroL) vrací informace o sdíleném segmentu a umožňuje jej modifikovat. Prvním parametrem je identifikátor sdíleného paměťového segmentu.

Chcete-li získat informace o segmentu, použijte jako druhý argument IPC_STAT a předejte funkci ukazatel na strukturu struct shmid_ds.

Chcete-li odstranit segment, předejte IPC_RMID jako druhý arguent a jako třetí argument zadejte NULL. Segment se odstraní v okamžiku, kdy se od něj odpojí poslední proces.

Každý sdílený paměťový segment by se měl explicitně dealokovat pomocí funkce shmctl() v okamžiku, kdy paměť přestanete používat. Funkce exit() a exec() totiž paměťové segmenty odpojí, ale ponechají je alokovány.

#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>

int main()
{
  int segment_id;
  char *shared_memory;
  struct shmid_ds shmbuffer;
  int segment_size;
  const int shared_segment_size = 0x6400;

  /* Alokovani sdileneho pametoveno segmentu */
  sgment_id = shmget(IPC_PRIVATE, shared_segment_size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);

  /* Pripojeni sdileneho segmentu */
  shared_memory = (char *) shmat(segment_id, NULL, NULL);
  printf("sdilena pamet byla pripojena na adresu %p\n", shared_memory);
  /* Urceni velikosti segmentu */
  shmctl(segment_id, IPC_STAT, &shmbuffer);
  segment_size = shmbuffer.shm_segsz;
  printf("velikost segmentu: %d\n", segment_size);
  /* Zapsani retezce do sdileneho pametoveho segmentu */
  sprintf(shared_memory, "Hello, world.");
  /* Odpojeni pametoveho segmentu */
  shmdt(shared_memory);

  /* Nove pripojeni sdileneho segmentu( na urcitou adresu) */
  shared_memory = (char *) shmat(segment_id, (void *) 0x5000000, NULL);
  printf("sdilena pamet byla pripojena na adresu %p\n", shared_memory);
  /* Vypis retezce ze sdilene pameti */
  printf("%s\n", shared_memory);
  /* Odpojeni segmentu */
  shmdt(shared_memory);

  /* Dealokovani sdileneho pametoveho segmentu */
  shmctl(segment_id, IPC_RMID, NULL);

  return(0);
} 

To by bylo pro dnešek vše, příště se podíváme na řízení přístupu do sdílené paměti pomocí semaforů.

Našli jste v článku chybu?

11. 1. 2012 1:45

feynman (neregistrovaný)

Docela by me zajimalo, jestli ma root.cz svoleni autoru knizky Pokrocile prog. v systemu Linux okopirovat a zverejnit jejich text. Pride mi to jako neskutecna drzost.

27. 11. 2010 14:16

Sebastian (neregistrovaný)

Dobrý den,

prosím Vás, nějak se mi nezdá, co píšete k flagu IPC_EXCL (konstante, priznaku,...).
Podle manualovych stranek se pise:

"IPC_CREAT to create a new segment. If this flag is not used, then shmget() will find the segment associated with key and check to see if the user has permission to access the segment.
IPC_EXCL used with IPC_CREAT to ensure failure if the segment already exists." [man shmget]

Z toho co pisete vy, mam pocit, ze pri pouziti flagu ICP_EXCL a pri exstenci klice se nev…



DigiZone.cz: Česká televize mění schéma ČT :D

Česká televize mění schéma ČT :D

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Podnikatel.cz: Víme první výsledky doby odezvy #EET

Víme první výsledky doby odezvy #EET

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

DigiZone.cz: ČT má dalšího zástupce v EBU

ČT má dalšího zástupce v EBU

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Lupa.cz: UX přestává pro firmy být magie

UX přestává pro firmy být magie

DigiZone.cz: NG natáčí v Praze seriál o Einsteinovi

NG natáčí v Praze seriál o Einsteinovi

120na80.cz: Rakovina oka. Jak ji poznáte?

Rakovina oka. Jak ji poznáte?

Podnikatel.cz: Prodává přes internet. Kdy platí zdravotko?

Prodává přes internet. Kdy platí zdravotko?