IPC-deljiva i mapirana memorija
IPC (
InterProcess Communication
) –
Međuprocesna komunikacija
IPC: deljiva i mapirana memorija
U okviru materijala iz prethodnog semestra, razmotren je sistemski poziv
wait
,
pomoću koga
jedan proces-roditelj može dobiti izlazni (
exit
) status od procesa deteta. To je
najjednostavnija forma komunikacije između dva procesa, ali ne i najmoćnija. Mehanizam
fork
,
exec
,
wait
,
exit
,
ne omogućava nijedan vid komunikacije roditelja i deteta izuzev preko
argumenata komandne linije i varijabli okoline, a ne omogućava ni bilo koji način
komunikacije deteta sa roditeljem izuzev preko detetovog izlaznog statusa. Nijedan od ovih
mehanizama ne pruža način ili sredstvo za komunikaciju sa procesom detetom dok je ono u
stanju izvršavanja, niti ovi mehanizmi dozvoljavaju komunikaciju sa procesima izvan odnosa
roditelj-dete.
U ovom tekstu su opisana sredstva za međuprocesnu komunikaciju koja zaobilaze ova
ograničenja. Predstavljeni su različiti načini komunikacije između roditelja i deteta, između
„nepovezanih“ procesa, pa čak i između procesa na različitim mašinama.
Interprocesna komunikacija (IPC) je prenos podataka između procesa.
Na primer, Web pretraživač može tražiti Web stranicu sa Web servera, koji zatim šalje HTML
podatke. Ovaj prenos podataka obično koristi soket mehanizam koji je nalik telefonskoj vezi.
U drugom primeru se želi odštampati imena datoteka u direktorijumu koristeći komandu ls |
lpr.
Shell
(komandni interpreter) stvara ls proces i poseban lpr proces, povezujući ova dva
procesa pomoću
pipe
(eng. cev, čita se „pajp“) mahanizma-datoteke, predstavljenog
simbolom „|“.
Pipe
mehanizam dozvoljava jednosmernu komunikaciju između dva srodna procesa. Proces
ls upisuje podatke u
pipe
, a proces lpr ih čita iz
pipe
-a.
Radićemo pet tipova interprocesne komunikacije, to su:
Deljiva memorija (
shared memory
) – dozvoljava procesima da komuniciraju
prostim čitanjem i upisivanjem u određenu memorijsku lokaciju.
Mapirana memorija – slična je deljivoj memoriji, izuzev toga što je povezana
sa datotekom u sistemu datoteka.
Pipe
datoteke – dozvoljavaju sekvencijalnu komunikaciju jednog procesa sa
srodnim procesom.
FIFO datoteke – nalik su na
pipe
, izuzev što i nepovezani procesi mogu
komunicirati jer FIFO datoteka ima dodeljeno ime u sistemu datoteka.
Soketi – podržavaju komunikaciju između nepovezanih procesa čak i na
različitim računarima.
Ovi tipovi IPC se razlikuju po sledećim kriterijumima:
Da li ograničavaju komunikaciju na srodne procese (procese sa zajedničkim pretkom),
na nepovezane procese koji dele isti sistem datoteka, ili na bilo koji računar povezan u
mrežu.
Da li je komunikacioni proces ograničen samo na upisivanje podataka ili samo na čitanje
podataka.
Broju procesa kojima je dozvoljeno da komuniciraju.
Da li su komunikacioni procesi sinhronizovani pomoću IPC - na primer proces čitanja je
u stanju čekanja sve dok pođaci ne postanu dostupni za čitanje.
Deljiva memorija
Jedna od najjednostavnijih metoda interprocesne komunikacije jeste upotreba deljive memorije.
Deljiva memorija omogućava da dva ili više procesa pristupe istoj memoriji ako pozovu
malloc
i
ako svi vraćeni pokazivači ukazuju na istu memoriju.
Kada jedan proces promeni neku memorijsku reč, svi ostali procesi vide promenu.
Brza lokalna komunikacija
Deljiva memorija je najbrža forma interprocesne komunikacije zato što svi procesi dele isti deo
memorije. Pristup ovoj deljivoj memoriji je onoliko brz koliko je to pristup procesovoj nedeljivoj
memoriji i ne zahteva sistemski poziv ili pristup kernelu. Takođe se izbegava nepotrebno
kopiranje podataka.
S ozbirom na to da kernel ne sinhronizuje pristupe deljivoj memoriji, korisnik treba da obezbedi
sopstvenu sinhronizaciju. Npr. proces ne bi trebalo da čita iz memorije dok se ne završi upis
podataka u nju, niti bi trebalo da dva procesa upisuju u istu memorijsku lokaciju u isto vreme.
Česta strategija za izbegavanje ovih stanja trke je upotreba semafora.
U programima koji su dati u primerima, prikazan je samo slučaj kada jedan proces pristupa
memoriji da bi fokus bio na mehanizmu deljive memorije i da bi se izbeglo komplikovanje kôda
primera sinhronizacionom logikom.

izvršenju
shmget
u slučaju da se zada ključ segmenta koji već postoji. Zbog toga, on
uređuje da pozvani proces uvek dobije poseban (ekskluzivan) nov segment. U slučaju da
ovaj fleg nije zadat a koristi se ključ već postojećeg segmenta,
shmget
vraća postojeći
segment umesto da kreira novi.
Mode flags
– ova vrednost je sačinjena od 9 bitova koji ukazuju na prava dodeljena
vlasniku, grupi i ostatku sveta (
others
) za kontrolu pristupa segmentu. Izvršni bitovi se
zanemaruju. Jednostavan način da se odrede prava je korišćenje konstanti definisanih u
<systat.h>. Na primer, S_IRUSR i S_IWUSR određuju prava čitanja i upisivanja za vlasnika
deljivog memorijskog segmenta, a S_IR0TH i S_IW0TH određuju prava čitanja i upisivanja
za ostale (
others
).
Na primer, ovakvo pozivanje
shmget
, kreira novi deljivi memorijski segment (ili pristup već
postojećem u slučaju da je
shm_key
već upotrebljen) u koji vlasnik može upisivati i čitati ga, ali je
nedostupan za druge korisnike.
int segment_id = shmget (shm_key, getpagesize(), IPC_CREAT | S_IRUSR | S_IWUSER);
U slučaju da poziv uspe,
shmget
vraća identifikator segmenta. Ako deljivi memorijski segment već
postoji, vrši se verifikacija prava pristupa i proverava se da li je segment označen za uništenje.
Pridruživanje i izbacivanje
Da bi deljivi memorijski segment učinio dostupnim, proces mora koristiti poziv
shmat
, „
Shared
Memory ATach”.
Parametri
shmat
:
Ovom pozivu treba proslediti identifikator deljivog memorijskog segmenta koji se dobija pomocu
shmget
.
Drugi argument je pokazivač, koji određuje gde u adresnom prostoru procesa korisnik želi da
mapira deljivu memoriju, a ako se odredi vrednost
NULL,
Linux će odabrati raspoloživu adresu.
Treći argument je fleg, koji može uključivati sledeće:
SHM_RND ukazuje da adresa koja je određena za drugi parametar treba da bude
zaokružena na umnožak veličine stranice. Ako se ne postavi ovaj fleg, potrebno je lično
podesiti drugi argument za
shmat
.
SHM__RDONLY ukazuje da će segment biti moguće samo čitati, a ne i upisivati.
Ako poziv
shmat
uspe, on vraća adresu pridruženog deljivog segmenta. Deca kreirana
fork
pozivom nasleđuju pridružene deljive segmente, a ako to žele, ona mogu izbaciti deljive
memorijske segmente iz svog prostora.
Kada se završi sa deljivim memorijskim segmentom, segment je potrebno izbaciti koristeći
shmdt („
SHared Memory DeTach").
Za
shmdt
treba koristiti adresu dobijenu pomoću
shmat
.
Ako se segment oslobodi i ako je ovo bio poslednji proces koji ga je koristio, on se uklanja.
Sistemski poziv
exit
ili pozivanje bilo kog člana
exec
familije, automatski izbacuje segment.
Kontrola i oslobađanje deljive memorije
Poziv shmctl ("
SHared Memory ConTroL
" - kontrola deljive memorije) vraća informaciju o
deljivom memorijskom segmentu i može ga modiflkovati.
Parametri
shmctl:
Prvi parametar je identifikator deljivog memorijskog segmenta.
Da bi dobili informaciju o deljivom memorijskom segmentu potrebno je proslediti: IPC_STAT
kao drugi argument i pokazivač na strukturu
shmid_ds
.
Za uklanjanje segmenta potrebno je proslediti: IPC_RMID kao drugi argument i NULL kao treći
argument. Segment se uklanja kada ga i poslednji proces koji ga je priključio (
attach
) konačno
izbaci (
detach)
iz svog adresnog prostora.
Svaki deljivi memorijski segment trebalo bi eksplicitno osloboditi (
deallocate
) koristeći
shmctl
kada se završi sa njim, da bi se izbeglo narušavanje sistemskog ograničenja u pogledu
ukupnog broja deljivih memorijskih segmenata. Sistemski pozivi exit i exec izbacuju (
detach)
memorijski segment, ali ga ne oslobađaju.
Za više informacija o
shmctl
možete pogledati
man
stranicu, tu je dat opis drugih operacija koje
se mogu obaviti nad deljivim memorijskim segmentima.
Primer upotrebe deljive memorije (
shm.c
):

Prevedite i pokrenite program:
$ gcc -o shm shm.c
$ ./shm
Izlaz programa je:
Otklanjanje grešaka
Komanda
ipcs
pruža informacije o osobinama interprocesne komunikacije,
uključujući i deljive segmente. Korišćenjem flega
-m
dobijaju se
informacije o deljivoj memoriji.
Na primer, ovaj kôd ilustruje da je u upotrebi jedan deljivi memorijski
segment sa brojem 1627649:
$ ipcs -m
Ako je ovaj memorijski segment greškom zaostao iza programa, moguće ga je
ukloniti komandom
ipcrm
.
$ ipcrm shm 1627649
Razlozi za i protiv deljive memorije
Deljivi memorijski segmenti dozvoljavaju brzu dvosmernu komunikaciju
između više procesa. Svaki korisnik može i čitati i upisivati, ali program
mora uspostaviti i poštovati neke protokole kako bi sprečio trku za
resursima, kao što je prepisivanje informacije pre čitanja.
Nažalost, Linux ne garantuje striktno ekskluzivan pristup, čak i kada se
kreira novi deljivi segment koristeći IPC_PRIVATE. Takođe, da bi više
procesa koristilo isti deljivi segment, potrebno je usaglasiti da koriste
isti ključ.
Ovaj materijal je namenjen za učenje i pripremu, ne za predaju.
Slični dokumenti