Document, comentariu, eseu, bacalaureat, liceu si facultate
Top documenteAdmitereTesteUtileContact
      
    


 


Ultimele referate adaugate

Adauga referat - poti sa ne ajuti cu un referat?

Politica de confidentialitate



Ultimele referate descarcare de pe site
  CREDITUL IPOTECAR PENTRU INVESTITII IMOBILIARE (economie)
  Comertul cu amanuntul (economie)
  IDENTIFICAREA CRIMINALISTICA (drept)
  Mecanismul motor, Biela, organe mobile proiect (diverse)
  O scrisoare pierduta (romana)
  O scrisoare pierduta (romana)
  Ion DRUTA (romana)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  Starea civila (geografie)
 

Ultimele referate cautate in site
   domnisoara hus
   legume
    istoria unui galban
   metanol
   recapitulare
   profitul
   caract
   comentariu liric
   radiolocatia
   praslea cel voinic si merele da aur
 
despre:
 
Memoria partajata - UNIX
Colt dreapta
Vizite: ? Nota: ? Ce reprezinta? Intrebari si raspunsuri
 

k6h7ht

La fiecare dintre metodele de comunicatie intre procese prezentate pina acum, informatia era transferata intre cele doua procese implicate, adica era copiata in afara spatiului de adresare al procesului sursa si apoi recopiata in spatiul de adresare al procesului destinatie, prin intermediul unor apeluri sistem. Acest lucru necesita unele transformari asupra datelor transferate si uneori, transferarea unor informatii suplimentare.
Atita timp cit cele doua procese comunica, ele trebuie sa se gaseasca deja in memorie impreuna cu datele lor. Daca datele de transmis se afla deja in memorie, cele doua procese pot accesa amindoua zona de memorie in care se gasesc datele comune. Aceasta memorie devine memoria partajata.
Folosirea memoriei partajate ofera o metoda eleganta si rapida de comunicatie intre cele doua procese care acceseaza in comun o zona de memorie interna. Aceasta zona poate fi folosita de oricare dintre procesele din sistem care ii cunosc cheia. Pentru fiecare proces care utilizeaza memoria partajata este necesar ca ea sa se gaseasca in spatiul sau de adresare. Acest lucru asigura de fapt eficienta maxima, in continuare aceasta zona fiind accesata ca si o variabila obisnuita, fara folosirea apelurilor sistem. Din pacate memoria partajata nu este disponibila in orice implementare de Unix System V pentru ca numai anumite configuratii hardware permit acest lucru. Folosirea unor zone de memorie in comun de catre doua procese impune desigur si o serie de restrictii de acces si necesitati de sincronizare care se rezolva de obicei cu ajutorul semafoarelor. Programarea defectoasa a accesului la memoria partajata a mai multor procese poate duce usor la blocaje (deadlocks).
Din punctul de vedere al programatorului, principiul de lucru cu memoria partajata este foarte simplu: un segment de memorie partajata trebuie creat si deschis, apoi atasat in spatiul de adresare al proceselor care au nevoie de el.
Apoi, fiecare dintre procese poate scrie sau citi fara restrictii din zona respectiva. Cind un proces nu mai are nevoie de memoria partajata, el poate detasa segmentul. Daca nici unul dintre procese nu mai are nevoie de el, segmentul de memorie partajata, poate fi eliminat complet. Pentru operatiile de creare, deschidere, atasare, detasare, eliminare a segmentelor de memorie partajata exista apeluri ale nucleului. Pentru accesarea datelor din segment nu exista apeluri, accesul facindu-se prin intermediul pointerilor.
Pentru a adresa segmentele de date procesoarele moderne folosesc un registru de segmentare. Daca este disponibil un astfel de registru, implementarea memoriei partajate este foarte usoara (acest lucru este rezolvat de cei care implementeaza UNIX-ul si nu de catre cei care folosesc memoria partajata in aplicatii!). Accesul ulterior la acest segment se face aproape la fel de repede ca la orice variabila locala a procesului, de aceea memoria partajata este de departe cea mai rapida metoda de comunicatie intre procese comparativ cu metodele prezentate pina acum.
Desigur, hardware-ul poate sa impuna si limitari. De exemplu numarul de segmente de memorie partajata care pot fi folosite deodata de catre un proces este dependent de arhitectura sistemului. Daca se doreste ca aplicatiile sa ramina portabile, nu trebuie folosit decit un singur element de memorie partajata. La fel hardware-ul determina si marimea maxima a unui segment. De obicei un minim de 64K este disponibil.
Pentru crearea si deschiderea unui segment de memorie partajata exista apelul sistem shmget. Se apeleaza in felul urmator:




#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h> key_t cheie; int marime, permisii, shmid;
... shmid=shmget(cheie, marime, permisii);
...
La fel ca si la mesaje, cel mai important parametru este primul, cheie, cel care da cheia de recunoastere globala a segmentului. Orice alt proces care vrea sa foloseasca segmentul de memorie partajata, creat cu shmget, trebuie sa cunoasca aceasta cheie. Cheia este, ca si mai inainte, de tipul key_t, dependent de implementare, dar de obicei un long. Al doilea parametru, marime, este cel care specifica dimensiunea in octeti a segmentului de memorie partajata care se doreste a fi cret. Ultimul parametru, permisii, specifica drepturile de acces la segment. Apelul returneaza in shmid un identificator al segmentului nou creat, care este local procesului. Daca apelul esueaza in crearea segmentului de memorie partajata, este intoarsa valoarea -1, iar eroarea va fi documentata in variabila globala errno. Valorile de eroare din errno sint dependente de implementare. Trebuie consultat manualele on-line pentru functia shmget(S).
Daca marimea specificata la apel pentru segment este prea mare sau prea mica, errno va fi setat pe valoarea EINVAL. Ce inseamna prea mic sau prea mare pentru implementarea data, trebui de asemenea aflat.
Pentru specificarea permisiilor, se pot folosi valori asemanatoare cu cele pentru cozi de mesaje. Trebuie deci specificate drepturile de acces la segment si citiva comutatori de creare. De exemplu poate primi valoarea
066 | IPC_CREAT | IPC_EXCL, deci drepturi de citire/scriere doar pentru proprietar, segmentul de memorie partajata va fi deschis numai daca nu exista deja, caz in care va fi mai intii creat. Daca segmentul exista deja se va intoarce valoarea de eroare -1.
Prin acest apel, a fost creat in memorie segmentul dorit. Accesul la el se va face in continuare prin intermediul identificatorului sau, shmid.
Acesta este local procesului curent, deci nu va avea aceasi valoare si pentru alte procese care deschid aceeasi zona de memorie partajata. La terminarea acestui apel segmentul nu este inca gata de a fi folosit pentru procesul curent. Aceasta din cauza ca segmentul nu se gaseste inca in spatiul de adresare al procesului. Pentru a atasa segmentul de memorie la proces exista apelul shmat (attach shared memory). El poate fi apelat dupa cum urmeaza:

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

int comutatori,shmid; char *adresa,*adresa_impusa;
... adresa=shmat(shmid, adresa_impusa, comutatori);
...

Prin acest apel se creaza pentru procesul curent o adresa virtuala cu care se va putea adresa in continuare zona de memorie partajata. Variabila adresa va contine dupa apel aceasta adresa. Prin apel se poate forta si legarea segmentului la o anumita adresa dorita, specificata prin parametrul adresa_impusa. Daca acest parametru are valoarea 0 si acesta este cazul comun, atunci sistemul va decide singur care este adresa unde va fi legat segmentul si aceasta va fi urmatoarea adresa disponibila.
Se poate de asemenea impune ca segmentul sa fie atasat la o adresa care sa fie inceput de pagina de memorie. Pentru aceasta trebuie specificata valoarea
SHM_RND in parametrul comutatori. Daca se impune o adresa de atasare, aceasta va fi rotunjita la urmatorul inceput de pagina. Daca nu, va fi intors urmatorul inceput de pagina. Daca nu, va fi intors urmatorul inceput de pagina disponibil.
Alt comutator disponibil este SHM_RDONLY, care specifica faptul ca segmentul trebuie protejat la scriere. Din pacate numai acele configuratii hardware pot asigura o astfel de protectie. Daca parametrul comutatori are valoarea 0, atunci accesul este si in citire si in scriere iar adresa nu va fi rotunjita in nici un fel.
Din acest moment acesul la segmentul de memorie este posibil prin adresa virtuala adresa. Se poate scrie si citi din memorie variabile intregi prin instuctiuni de genul:

int i, *pint;

pint=(int *)adresa;
*pint++=i;
... i=*pint;
...
Sau se poate adresa segmentul caracter cu caracter in felul urmator:

int i;

for(i=0;adresaaii;i++)
...;

Dupa terminarea lucrului cu memoria partajata aceasta trebuie desigur eliminata din spatiul de adresare al procesului. Acest lucru se face cu ajutorul apelului shmdt (detach shared memory). Acesta se apeleaza astfel:

... retur=shmdt(adresa);
...

Dupa acest apel nu se mai poate adresa in nici un fel segmentul de memorie partajata, decit dupa o noua atasare. In clipa in care toate procesele care aveau nevoie de segmentul de memorie partajata s-au detasat de la acesta, segmentul poate fi distrus complet printr-un apel shmctl. Apelarea se face astfel:

... retur=shmctl(shmid, IPC_RMID, 0);
...

Trebuie acordata foarte mare atentie la distrugerea unui segment de memorie partajata. Daca mai exista procese care au atasat acel segment pot apare erori foarte grave, care sa duca chiar la caderea sistemului !
Urmatorul exemplu de program se poate urmari fara explicatii suplimentare.
In program memoria partajata este atasata si detasata la fiecare acces. Acest lucru nu este in general necesar si trebuie evitat pe cit posibil datorita pierderii de viteza. S-a folosit aceasta metoda pentru ca in unele implementari mai vechi de Unix (de exemplu Xenix) o zona de memorie partajata nu poate fi atasata deodata la mai multe procese. Aceasta limitare nu mai este valabila in implementarile moderne.
In diverse implementari de Unix, au aparut multe optiuni suplimentare in lucrul cu memoria partajata. Filozofia de baza a Unix-ului este valabila si in acest caz "Keep it small, keep it simple".

/* shmem.h */

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

#define SHMKEY (key_t)100

/* scrie.c */

#include "shmen.h"

int shmid;

main()
A int i; char *adresa; extern cleanup();

/*Captarea tuturor semnalelor*/ for(i=0;i < 20;i++) signal(i, cleanup);
/*crearea zonei de memorie partajata*/
/*marimea este de 4096 octeti*/
/*identificator SHMKEY*/ shmid=shmget(SHMKEY, 4096, 0660|IPC_CREAT); i=0;
while(1)
A
/*legarea in spatiul de adrese*/ adresa=shmat(shmid, 0, 0);

/*scrierea mesajului in memoria partajata*/ sprintf(adresa, "%6d hello,world!",i++);

/*dezlegarea din spatiul de adrese*/ shmdt(adresa);
S
S cleanup()
A shmctl(shmid, IPC_RMID, 0); exit();
S

/* citeste.c */

#include "shmen.h"

int shmid;

main()
A int i,*pint=0; char *adresa;

/*deschiderea zonei de memorie partajata*/ shmid=shmget(SHMKEY, 2048, 0660); for(i=0;i < 20;i++) A
/*legarea la spatiul de adresare*/ adresa=shmat(shmid, 0, 0);

while(*pint==0);
/*nu citeste pina nu este gata driverul*/

/*citirea mesajului*/ printf("%s\n",adresa);

/*dezlegarea din spatiul de adresare*/ shmdt(adresa); sleep(1);
S
S


Colt dreapta
Creeaza cont
Comentarii:

Nu ai gasit ce cautai? Crezi ca ceva ne lipseste? Lasa-ti comentariul si incercam sa te ajutam.
Esti satisfacut de calitarea acestui document, eseu, cometariu? Apreciem aprecierile voastre.

Nume (obligatoriu):

Email (obligatoriu, nu va fi publicat):

Site URL (optional):


Comentariile tale: (NO HTML)


Noteaza documentul:
In prezent fisierul este notat cu: ? (media unui numar de ? de note primite).

2345678910

 
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite
Colt dreapta