Sunteți pe pagina 1din 2

Programarea aplicatiilor de timp-real

Laborator 4

Mecanisme de sincronizare si comunicare sub QNX / POSIX.


Semafoare. Sincronizarea firelor de executie.
Semafoarele reprezinta un mecanism simplu de programare pentru excludere mutuala si
sincronizare pe anumite conditii, care pot fi utilizate atat pentru operatiile executate de procese, cat
si pentru cele executate de firele de executie. Operatiile care pot fi executate pe un semafor,
conform standardului POSIX, sunt de tip “post” (sem_post() - echivalentul operatiei standard pe
un semafor, signal) sau “wait”(sem_wait() echivalentul operatiei standard pe un semafor, wait).
Operatia de tip "post" realizeaza incrementarea semaforului in timp ce operatia de tip “wait” il
decrementeaza.

Semafoarele implementate in standardul POSIX sunt de tip generalizat (engl. counting


semaphores). Astfel, un fir de executie care asteapta pe un semafor cu valoare pozitiva nu se va
bloca, dar asteptarea pe un semafor negativ duce la blocarea firului respectiv pana cand se va
executa o operatie de tip “post” (din alt proces / fir de executie). Se pot executa mai multe
decrementari ale unui semafor inainte de a realiza o incrementare. Acest lucru permite unuia sau
mai multor fire de executie sa execute incrementari fara a se bloca.

Pentru o eficienta sporita, standardul POSIX recomanda utilizarea semafoarelor pentru


sincronizarea proceselor. De asemenea, folosind un manager de resurse, se pot utiliza semafoarele
pentru sincronizarea proceselor care ruleaza pe sisteme diferite, conectate in retea.

Deoarece semafoarele, ca si variabilele conditionale, pot returna valori nenule datorate unor
false “treziri”, folosirea corecta presupune utilizarea unui ciclu “while” de forma urmatoare:

while (sem wait(&s) && errno == EINTR){


nu face nimic();
}
executa_regiunea_critica();

Tabel Interfata C / POSIX pentru semafoare


Functia1 Descriere
int sem_init(sem_t* sem, int pshared, unsigned value);
Initializeaza semaforul “sem” cu valoarea “value”. Daca variabila
“pshared” este diferita de zero, semaforul poate fi partajat intre procese
printr-o zona comuna de memorie.
int sem_destroy(sem_t* sem);
Distruge semaforul “sem”. Dupa distrugere, el nu mai poate fi folosit decat
dupa initializare.
int sem_getvalue(sem_t* sem, int* value);
Citeste valoarea semaforului “sem” si o stocheaza in variabila “value”.
Daca value == 0, semaforul este locked, daca value > 0 semaforul este
unlocked.

1
Toate functiile returneaza 0 in caz de succes si -1 in caz de eroare
1
int sem_post(sem_t* sem);
Incrementeaza valoarea semaforului “sem”. Daca exista procese ce asteapta
la semafor, unul din ele va reveni din sem_wait(). Procesul cu prioritatea
cea mai mare va fi deblocat, iar in cazul in care sunt mai multe procese cu
prioritate maxima, va fi deblocat cel care asteapta de cel mai mult timp.
int sem_wait(sem_t* sem);
Decrementeaza valoarea semaforului “sem” si, daca valoarea sa nu este mai
mare de zero, blocheaza procesul care a apelat-o. Procesul isi poate
continua executia daca alte procese incrementeaza valoarea semaforului
int sem_trywait(sem_t* sem);
Wait fara blocare. Decrementeaza valoarea semaforului “sem” daca
valoarea sa este mai mare de zero, altfel face doar return.

Desfasurarea lucrarii:

Exemplu:
Utilizarea semafoarelor pentru sincronizarea firelor de executie.
Sincronizare de tip one-to-many.

Se considera o aplicatie formata din doua tipuri de taskuri: un task (fir de executie)
"producator" care produce un set de date si mai multe taskuri (fire de executie) de tip "consumator"
care consuma datele. Taskul "producator" va putea produce un nou set de date doar dupa ce toate
taskurile de tip "consumator" au preluat datele.

Pentru compilarea programului se executa comanda:

$ qcc ./ex_sem_thread.c -o ./ex_sem_thread.out

Lansarea in executie a programului:

$ ./ex_sem_thread.out

S-ar putea să vă placă și