Sincronizare prin semafoare
Dijkstra a introdus un nou mecanism pentru excluderea mutuala intre un numar oarecare de procese, semaforul. Pentru aceasta, semaforul se asociaza resurselor sau grupurilor de resurse. Semaforul este o structura care contine :
- un contor (intreg)=valoarea semaforului;
Daca este pozitiv, reprezinta numarul de resurse disponibile asociate semaforului; daca este negativ, reprezinta numarul de procese din coada de asteptare. Daca este zero, nici o resursa nu este disponibila.
- o coada in care sunt introduse procesele in asteptare;
- doua operatii atomice (a caror executie nu poate fi intrerupta). Se garanteaza ca odata ce a inceput o operatie pe semafor, nici un alt proces nu il mai poate accesa, evitandu-se astfel conditiile de cursa. Cele doua operatii sunt :
Operatia DOWN este executata de un proces care doreste sa castige acces la resursa asociata semaforului. Operatia decrementeaza valoarea semaforului (contorul). Daca inaintea decrementarii contorul era pozitiv, executia procesului poate continua. Daca valoarea era zero sau negativa, executia procesului este intrerupta si procesul se introduce in coada semaforului (procesul ramane blocat pana cand resursa este disponibila).
Operatia UP este executata de proces imediat dupa eliberarea resursei. Operatia incrementeaza valoarea semaforului. Daca ea era negativa, este relansat primul proces din coada de asteptare a semaforului, acesta primind acces la resursa proaspat eliberata.
Daca programul este scris incorect, executia poate ajunge in doua stari ce exprima imposibilitatea de terminare a programului :
-impas : stare ce semnifica blocarea reciproca a proceselor;
-ciclu infinit : executia repetata a unor operatii (programul ruleaza dar nu avanseaza).
Un semafor care poate lua doar valorile 0 si 1 se numeste semafor binar.
Particularitatea sincronizarii prin intermediul semafoarelor in cadrul nucleului UNIX este ca se pot executa operatii pe o multime de semafoare printr-un singur apel de functie.
!! ce urmeaza trebuie pus si la laborator
struct semid_ds ;
union semun ;
struct sembuf ;
SEM_UNDO : operatia va fi anulata (undone) cand procesul se termina.
Creare set de semafoare :
int semget(key_t key, int nsems, int semflg);
key=cheia resursei (semaforul va fi asociat valorii acestei variabile);
nsems=numarul de semafoare din set; trebuie sa fie cuprins intre 1 si numarul maxim posibil care este o constanta a sistemului;
semflg= IPC_CREAT - creeaza o noua intrare daca key nu exista;
= IPC_EXCL - se returneaza eroare daca key exista;
Aceasta functie returneaza creeaza un set de semafoare si returneaza identificatorul asociat acestuia. Daca key=IPC_PRIVATE , setul de semafoare poate fi accesat doar de parinte si fiii sai
Dupa creare, cei mai putin semnificativi 9 biti din semflg definesc drepturile de acces (pentru user, grup si ceilalti)
Operare asupra setului de semafoare :
int semop(int semid, struct sembuf *sops, unsigned nsops);
semid=identificatorul setului de semafoare returnat de semget;
sops=pointer catre setul de semafoare;
nsops=numarul de elemente din setul de semafoare;
sops.sem_op>0, se aduna aceasta valoare la valoarea semaforului (semval) : operatia UP;
=0 si semval=0,procesul doreste sa astepte pana cand semval devine zero; ??
<0, se scade valoarea absoluta a lui sops.sem_op din semval : operatia DOWN;
int semctl(int semid, int semnum, int cmd, union semun arg);
functie de control asupra semaforului;permite procesului apelant sa obtina informatii despre setul de semafoare iedntificat prin semid, sa pozitioneze drepturile de acces pentru proprietar si grup sau sa distruga setul de semafoare;
semid= identificatorul setului de semafoare;
semnum=semaforul asupra caruia se efectueaza comanda cmd
cmd=IPC_STAT, informatiile din semafor sunt copiate in arg.buf; semnum este ignorat; utilizatorul trebuie sa aiba drepturi de citire a setului de semafoare;
IPC_SET, informatiile din arg.buf sunt copiate in structura semaforului; semnum este ignorat;
IPC_RMID, sterge setul de semafoare si structurile de date asociate;
SETVAL, se atribuie semaforului semnum valoarea arg.val ;
SETALL, se atribuie semafoarelor valorile din arg.array; semnum este ignorat;
GETVAL, returneaza valoarea semaforului semnum; arg este ignorat;
GETALL, returneaza valorile setului de semafoare in arg.array; semnum este ignorat;
Prin apelul sistem fork() se creeaza o copie a datelor, deci cele doua procese acceseaza copii ale aceleiasi variabile. Deoarece exista cazuri cand este necesar ca doua procese sa aiba acces la aceeasi variabila, s-a introdus conceptul de "memorie comuna" (shared memory).
Procesele pot schimba date intre ele folosind valorile unor variabile comune stabilite in mod static la inceputul executiei programului.
Crearea unei zone de memorie:
int shmget(key_t key, int size, int shmflg);
size=dimensiunea=multiplu de PAGE_SIZE
shmflg= IPC_CREAT, IPC_EXCL, 9 biti ce exprima drepturile de acces;
creeaza un nou segment de memorie de dimensiunea specificata si ii returneaza adresa de inceput;
Daca key=IPC_PRIVATE, apelul ia in considerare doar cei mai putin semnificativi 9 biti din semflg si creeaza un nou segment de memorie.
Daca shmflg=IPC_CREAT, apelul sistem creeaza un nou segment. Daca nu, va cauta segmentul asociat cheii key, va verifica daca utilizatorul are drepturi de acces la el si in caz afirmativ ii va returna adresa de inceput.
Daca shmflg=IPC_EXCL, apelul sistem va returna eroare daca cheia key exista in sistem.
Un proces isi asociaza la spatiul sau de adrese zona de memorie comuna creata de sistem, folosind apelul sistem :
char *shmat(int shmid, char *shmaddr, int shmflg);
ataseaza segmentul de memorie segmentului de date al procesului apelant
shmid=identificatorul zonei de memorie comuna, returnat de shmget
shmaddr= adresa de inceput; daca este 0, SO este cel care cauta o regiune nemapata;
shmflg=SHM_RDONLY - segmentul poate fi accesat doar pentru citire; altfel, poate fi accesat si pentru citire si pentru scriere;
Dezasocierea se realizeaza prin :
int shmdt(char *shmaddr);
Eliberarea zonei de memorie alocata prin shmget :
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
functie de control asupra segmentului de memorie partajat; permite procesului apelant sa obtina informatii despre segmentul de memorie comuna identificata prin semid, sa pozitioneze drepturile de acces pentru proprietar si grup sau sa distruga setul de semafoare;
cmd=IPC_STAT, copiaza informatiile despre zona de memorie comuna in buf ; utilizatorul trebuie sa aiba dreptul de citire al zonei de memorie comuna;
IPC_SET, modifica permisiunile(uid, gid, moduri de acces); pentru a putea executa aceasta operatie, utilizatorul trebuie sa fie proprietarul, creatorul sau superuser-ul;
IPC_RMID, stergerea zonei de memorie comuna.
Procesele fii mostenesc segmentele de memorie partajata pe care procesul parinte le are asociate. Apelurile sistem exec() si exit() determina ca toate segmentele de memorie sa fie dezasociate (nu distruse).
Politica de confidentialitate |
.com | Copyright ©
2024 - Toate drepturile rezervate. Toate documentele au caracter informativ cu scop educational. |
Personaje din literatura |
Baltagul – caracterizarea personajelor |
Caracterizare Alexandru Lapusneanul |
Caracterizarea lui Gavilescu |
Caracterizarea personajelor negative din basmul |
Tehnica si mecanica |
Cuplaje - definitii. notatii. exemple. repere istorice. |
Actionare macara |
Reprezentarea si cotarea filetelor |
Geografie |
Turismul pe terra |
Vulcanii Și mediul |
Padurile pe terra si industrializarea lemnului |
Termeni si conditii |
Contact |
Creeaza si tu |