7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta http://slidepdf.com/reader/full/modernmultithreading-semafoare-si-zavoare-versiune-beta 1/60 3. SEMAFOARE SI ZAVOARE Semafoarele si zavoarele sunt obiecte folosite pentru sincronizare. Semafoarele sunt folosite in excluderea mutuala si sincronizarea conditionala. Zavoarele sunt de asemenea folosite in excluderea mutuala si au proprietati speciale care le fac utile in programele orientate-obiect. In acest capitol vom invata cumsa folosim semafoare si zavoare pentru a crea sectiuni critice si pentru a rezolva diferite probleme de programare. Apoi vom vedea cum se comporta semafoarele si zavoarele in Java, Win3 si !t"reads. In final,vom arata cum sa contruim semafoare personali- zate si clase de zavoare care suporta testari si rulari multiple. 3.# SEMAFOARE NUMARATOARE $n semafor numarator este un obiect de sincronizare care se initializeaza cu o valoare intreaga si se acceseaza prin operatii, numite ! si % &'i()stra #*+. Aceste operatii sunt numite uneori jos si sus, de decrementare si incrementare, sau respectiv asteapta si semnal. /lasele din librariile noastre de sincronizare suporta toate aceste tipuri de denumiri.0. 1raditional, un semafor numarator este definit ca o variabila speciala cu valoare intreaga care este folosita ca un parametru de catre procedurile !0 si %0. 2oi folosim o definitie orientata-obiect in care un semafor numarator este o instanta a clasei countingSemaphore . class countingSemap"ore public countingSemap"oreint initial!ermits0 permits 4 initial!ermits56 public void !0 ...65 public void %0 ...65 private int permits5 6 /and se defineste comportamentul metodelor !0 si %0, este utila intepreta rea in care un semafor numarator are un rezervor de permisiuni. $n fir apeleaza metoda !0 pentru a obtine o permisiune. 'aca rezervorul este gol, firul asteapta pana cand o permisiune devine disponibila. $n fir apeleaza metoda %0 pentru a returna o permisiune catre rezervor. $n semafor numarator s este declarat si initiazat folosind7 countingSemap"ore s#05 %aloarea initiala, in acest caz #, reprezinta numarul initial de permisiuni din rezervor. In sc"ema care urmeaza este prezentata una din posibilele implementari ale metodei !0 si %0. %ariabila privata de permisiuni de tip intreg memoreaza numarul curent de permisiuni din rezervor7 public void ! 0 if permits 8 90 --permits5 :: ia o permisiune din rezervor else :: rezervorul este gol si asteapta o permisiune asteapta pana cand permisiunea devine pozitiva si apoi decrementeaza permisiunea cu 1.
60
Embed
Modern_Multithreading Semafoare Si Zavoare Versiune Beta
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
Semafoarele si zavoarele sunt obiecte folosite pentru sincronizare. Semafoarele suntfolosite in excluderea mutuala si sincronizarea conditionala. Zavoarele sunt de asemenea folosite
in excluderea mutuala si au proprietati speciale care le fac utile in programele orientate-obiect. In
acest capitol vom invata cumsa folosim semafoare si zavoare pentru a crea sectiuni critice si pentru a rezolva diferite probleme de programare. Apoi vom vedea cum se comporta semafoarele
si zavoarele in Java, Win3 si !t"reads. In final,vom arata cum sa contruim semafoare personali-
zate si clase de zavoare care suporta testari si rulari multiple.
3.# SEMAFOARE NUMARATOARE
$n semafor numarator este un obiect de sincronizare care se initializeaza cu o valoareintreaga si se acceseaza prin operatii, numite ! si % &'i()stra #*+. Aceste operatii sunt numite
uneori jos si sus, de decrementare si incrementare, sau respectiv asteapta si semnal. /lasele din
librariile noastre de sincronizare suporta toate aceste tipuri de denumiri.0. 1raditional, un semafor
numarator este definit ca o variabila speciala cu valoare intreaga care este folosita ca un parametru de catre procedurile !0 si %0. 2oi folosim o definitie orientata-obiect in care un
semafor numarator este o instanta a clasei countingSemaphore .
class countingSemap"ore
public countingSemap"oreint initial!ermits0 permits 4 initial!ermits56 public void !0 ...65
public void %0 ...65
private int permits5
6
/and se defineste comportamentul metodelor !0 si %0, este utila intepreta rea in care unsemafor numarator are un rezervor de permisiuni. $n fir apeleaza metoda !0 pentru a obtine o permisiune. 'aca rezervorul este gol, firul asteapta pana cand o permisiune devine disponibila.
$n fir apeleaza metoda %0 pentru a returna o permisiune catre rezervor. $n semafor numarator s
este declarat si initiazat folosind7
countingSemap"ore s#05
%aloarea initiala, in acest caz #, reprezinta numarul initial de permisiuni din
rezervor. In sc"ema care urmeaza este prezentata una din posibilele implementari ale metodei !0
si %0. %ariabila privata de permisiuni de tip intreg memoreaza numarul curent de permisiuni dinrezervor7
public void ! 0 if permits 8 90
--permits5 :: ia o permisiune din rezervor
else :: rezervorul este gol si asteapta o permisiune
asteapta pana cand permisiunea devine pozitiva si apoi decrementeaza permisiunea cu 1.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
;;permits5 :: returneaza o permisiune in rezervor 6
'aca un fir apeleaza !0 cand valoarea permisiunii este zero, asteapta pana cand permisiunea este pozitiva, o decrementeaza, iar apoi paraseste !05 in caz contrar, permisiunea
este pozitiva si firul o decrementeaza si exista !0. <etoda %0 incre- menteaza permisiunea si
niciodata nu bloc"eaza firul care o apeleaza. =ste posibil ca mai multe fire sa astepte in !0 pentru o permisiune. >irul care asteapta si pri-meste o permisiune ca rezultat al unei operatii %0
nu este neaparat firul care a asteptat cel mai mult.
!entru un semafor numarator s, in orice moment de timp, urmatoarea relatie este valabila7
numarul initial de permisiuni0 ; numarul de operatii s.%0 terminate0?numarul de operatii s.!0 terminate0.
Aceasta relatie mai poarta si denumirea de invariant pentru semaforul s. Atentie ca invariant se
refera operatiile !0 si %0 terminate. $n fir care porneste o operatie !0 poate sa fie blocat in !0,deci s-ar putea ca operatia sa nu fie executata imediat. Asa ca numarul de operatii !0 terminate
poate fi mai mic decat numarul de operatii !0 incepute. !entru un semafor numarator, operatiilede tip %0 nu bloc"eaza niciodata apelantul si intotdeauna sunt terminate imediat.
%om evita sa facem referire la @valoarea semaforului s cand descriem com-portamentul
lui s, din moment ce valoarea unui semafor nu este definita clar. 'eobicei, valoarea unui semafor este data de numarul de permisiuni valabile, care este de asteptat sa fie un numar non-negativ. In
implementarea de mai sus, variabila permits reprezinta numarul de permisiuni valabile, iar
aceasta nu este niciodata negative, deci poate fi folosita ca @valoarea lui s. /u toate acestea,
acest detaliu de implementare nu este intotdeauna valabil. In alte implementari ale lui !0 si %0,variabila permits poate avea o valoare negativa cand firele asteapta o permi-siune.
/lasa countingSemaphore nu furnizeaza metode pentru accesul la valoarea unui semafor5
doar !0 si %0 sunt furnizate. /"iar daca valoarea ar fi disponibila, nu ar fi utila din moment ce poate fi modificata de o operatie !0 sau %0 imediat dupa ce aceasta a fost retrasa. 'e aceea, ne
bazam pe invariantul unui semafor pentru ai defini comportamentul. Implementarea de mai sus
defineste !0 si %0 fara sa specifice detalii despre cum se implementeaza operatia wait in !0 saucum sa fie asigurata excluderea mutuala pentru accesul variabilei parta(ate permits. <ai tarziu
vom discuta despre aceste probleme de implementare si vom prezenta imple-mentari Java si /;;
ale clasei countingSemaphore.
3. >BCBSID=A S=<A>BAD=CBD
!entru a invata cum se folosesc semafoarele este nevoie de exercitiu. 'ar exista nisteidiome si minisabaloane comune cu care semafoarele pot fi folosite pentru a rezolva problema.
Aceste sabloane sunt decrise mai (os. Decunoasterea si aplicarea acestor sabloane este primul pas
spre a intelege si a scrie programe bazate pe semafoare.
3..#. ACB/AD=A D=S$DS=CBD
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
/onsiderati problema in care trei fire de executie concureaza pentru doua resurse. 'aca
nici una din resurse nu este disponibila, un fir trebuie sa astepte pana cand una din resurse este
eliberata de catre alt fir. !unctul 3.# ne prezinta o solutie cu semafor pentru aceasta problema;countingSemaphore s este initializat la , unde este numarul initial de resurse disponibile.
Apelurile catre s.P() si s.V() inco(oara sectiunea de folosire a resurselor. 'aca doua fire din cele
trei folosesc resurse, al treilea fir va fi blocat cand va executa operatia s.!0. $n fir care executa ooperatie s.%0 face ca resursa sa, sa fie disponibila pentru alte fire. Asta inseamna ca un fir care
este blocat intr-o operatie s.!0 va fi deblocat cand se va executa o operatie de tip s.%0.
Invariantul semaforului s si plasarea operatiilor !0 si %0 ga-ranteaza ca nu pot exista mai multde doua operatii s.!0 terminate fara interventia unei operatii s.%0.
countingSemap"ore s05 ::doua resurse sunt valabile initial
Semafoarele numaratoare sunt o solutie perfecta la problema alocarii resurselor.
Dezervorul de permisiuni reprezentat de semaforul s, indica direct catre rezervorul de resurse
administrat. 'e exemplu, daca valoarea lu s.permits este , sunt valabile resurse. <etodele !0si %0 se ocupa de toata administrarea interna necesara7 numara resurele, verifica numarul
disponibil de resurse si bloc"eaza fire cand nu exista resurse disponibile. 'in pacate, o solutie
atat de simpla nu exista pentru fiecare problema. $nele probleme cer ca operatiile de
administrare sa fie facute in afara operatiilor !0 si %0, iar semafoarele sa fie folosite pentru altelucruri pe langa administrarea resurselor.
3.. SABLOANE DE SEMAFOARE SUPLIMENTARE
=xemplul 3. prezinta o solutie alternativa la problema alocarii resurselor. Aceasta solutie
este mult mai complicata, dar ilustreaza cateva sabloane folosite mai des. In aceasta solutie,variabila parta(ata count monitorizeaza numarul de re-surse disponibile. %ariabila count este
initializata cu valoarea . /and valoarea variabilei count este mai mare decat zero, inseamna ca
exista o resursa disponibila.
%aloarea variabilei count este decrementata atunci cand o resursa este luata si incrementata cando resursa este eliberata. %ariabila parta(ata waiting monitorizea-za numarul firelor in asteptare.
/and un fir doreste sa utilizeze o resursa, verifica valoarea variabilei count. 'aca aceasta valoare
este mai mica sau egala cu zero, firul incrementeaza varibila waiting si apoi se autobloc"eazaexecutand operatia resourceAvailable.P(). /and un fir elibereaza o resursa, verifica valoarea
variabilei waiting . 'aca aceasta valoare este mai mare decat zero, un fir in asteptare este anuntat
ca exista o resursa disponibila5 in caz contrar, variabila count este incre-mentata pentru cacererile viitoare pentru resurse sa fie aprobate. Bbservam ca variabila count nu este incrementata
cand un fir in asteptare este notificat, la fel cum si count nu este decrementata dupa ce un fir in
asteptare primeste o resursa.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
#ntra$si$%esteaza 'eseori, un fir va intra intr-o sectiune critica si apoi va testa o conditie care
implica variabile parta(ate. In exemplul 3., testul pentru disponibili-tatea resurselor urmaresteapelul la mute!.P()"
mutex.!05if count890 :: testeaza disponibilitatea resurselor5 count este o variabila
parta(ata
...5 :: count&' inseamna ca o resursa este disponibila6
else
...5
resourceAvailable.!05 :: asteapta pentru o resursa6
B alternativa la declararea i va contine o operatie !0, pentru ca firul sa se poata
autobloca pana cand este anuntat ca a fost satisfacuta conditia. #esi$#nainte$Sa astepti $n fir care se executa in interiorul unei sectiuni critice, va iesi din ea
inainte sa se bloc"eze peste o operatie !0. #esi$#nainte$Sa asteptieste necesar din moment ce un fir care se autobloc"eaza intr-o sectiune critica poate sa creeze o
situatie de dead-loc). In exemplul 3., cand nu este nici o resursa disponibila, mute!.V() este
executat inainte de resourceAvailable.P().
mutex.%05 :: iesire din sectiunea critica
resourceAvailable.!05 :: asteapta pentru o resursa
'aca un fir nu a apelat mute!.V() pentru a iesi din sectiunea critica inainte sa apeleze
resourceAvailable.P() alte fire nu vor putea sa intre in sectiunea critica, si nu vor aparea apeluri
la resourceAvailable.V(). #esi$#nainte$Sa astepti este un sablon folositor, dar este deasemenea sisursa unor erori de programare subtile. In Sectiunea 3.H vom arata cum sa facem acest sablon
mai sigur.
*onditia Statului la *oada + $n semafor poate fi folosit ca o coada de fire care as-teapta ca oconditie sa devina adevarata. 'aca valoarea initiala a unui semafor s este zero si numarul de
operatii s.P() incepute nu este niciodata mai mic decat numarul de operatii s.V() terminate,
invariantul semaforului asigura ca fiecare ope- ratie s.P() bloc"eaza garantat firul apelant.
Aceasta indica faptul ca s este folosit ca o coada, nu ca un contor de resurse.In exemplul 3., semaforul resourceAvailable este folosit ca o coada de fire care asteapta ca o
resursa sa devina disponibila. Semaforul resourceAvailable este initi-alizat la zero si toate
operatiile resourceAvailable.V() sunt executate cand cel putin un fir asteapta7
if Faiting890 :: daca unul sau mai multe fire asteapta
resourceAvailable.%05 :: atunci anunta un fir blocat
In aceste conditii, un apel la resourceAvailable.P() intotdeauna va bloca firul apelant, iar un apel
la resourceAvailable.V() intodeauna va debloca un fir in asteptare. Aceste sabloane reprezinta
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
baza in construirea solutiilor bazate pe sema- foare. %om vedea aceste sabloane si alte cateva
folosite de-a pe parcusul exemple-lor din sectiunea 3..
3.3 SEMAFOARE BINARE SI ZAVOARE
Sablonul cu mute! este cel mai folosit sablon cu semafor si merita studiat in detaliu. $nsemafor numit mute! este initializat cu valoarea #. Apelurile la mute!.P() si mute!.V() creeaza o
'atorita valorii initiale # a mute!$ului si a plasarii lui mute!.P() si mute!.V() in (urul sectiuniicritice, o operatie mute!.P() va fi terminata prima, apoi mute!.V() si apoi mute!.P() si tot asa
mai departe. !entru acest sablon, putem lasa mutexul sa functioneze ca un semafor numarator,sau putem folosi un tip de semafor mai re-strictiv numit semaor binar.
$n semafor binar trebuie initializat cu valoarea # sau 9, iar terminare opera- tiilor !0 si
%0 trebuie sa alterneze. Atentie ca operatiile !0 si %0 pot fi pornite in orice ordine, dar terminarea lor trebuie sa fie alternativa.0. 'aca valoarea initiala a semaforului este #, care este
cazul sectiunilor critice, prima operatie care trebuie terminata este !0. 'aca o operatie %0 este
incercata intai, aceasta va bloca apelan- tul ei. Similar, daca valoarea initiala a semaforului este
9, prima operatie teminata trebuie sa fie de tip %0. 'eaceea, operatiile !0 si %0 ale unuisemafor binar pot bloca firele apelante. Amintiti-va sa semafoarele numaratoare au operatia !0
de blocare, dar operatia %0 nu bloc"eaza niciodata firul care o apeleaza.
$n al treilea tip de obiect de sincronizare se numeste zavor mute! sau mai simplu zavor poate fi folosit pentru a rezolva problema sectiunii critice.
Zavoarele asigura excluderea mutuala dar nu si conditia de sincronizare0. Bpera-tiile aplicate
unui zavor se numesc loc,() si unloc,(). Sablonul ute! pentru zavoa-re si semafoare arata lafel7
mutexCoc) mutex5
1"read# 1"readmutex.loc)05 mutex.loc)05
:E sectiune critica E: :E sectiune critica E:
mutex.unloc)05 mutex.unloc)05
Spre deosebire de un semafor, un zavor are un detinator, iar aceasta proprietate de a fi detinut
(oaca un rol important in comportamentul unui zavor7
• $n fir trimite o cerere de detinere a zavorului C, apeland -.loc,().
• $n fir care apeleaza -.loc,() devine detinatorul daca zavorul nu este detinut de alt fir5
contrar, firul este blocat.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
• $n fir elibereaza detinerea lui C apeland -.unloc,(). 'aca firul nu il detine pe C, apelul la
-.unloc,() genereaza o eroare.
• $n fir care detine de(a zavorul C si apeleaza -.loc,() din nou, nu este blocat. 'e fapt, este
normal pentru un fir sa ceara si sa primeasca detinerea unui zavor care de(a il detine. 'ar firul detinator trebuie sa apeleze -.unloc,() de acelasi numar de ori care a apelat -.loc,()
inainte ca alt fir sa devina detina-torul lui C.• $n zavor care permite firului de care este detinut sa fie blocat din nou se numeste zavor
recursiv.
Zavoarele sunt folosite deobicei in metodele claselor. Acest lucru este ilustrat de urmatoareaclasa7
class loc)ableBb(ect public void >0
mutex.loc)05
...5
mutex.unloc)056
public void 0
mutex.loc)05...5 >05 ...5 :: metoda () apeleaza metoda /()
mutex.unloc)05
6 private mutexCoc) mutex5
6
Zavorul mute! in cadrul clasei loc,able0bject este folosit pentru a transforma metodele >0 si
0 in sectiuni critice. 'eaceea, doar un singur fir la un moment-dat poate fi executat in cadrulmetodei loc,able0bject. /and un fir apeleaza meto-da 0, mutex-ul este blocat. /and metoda
0 apeleaza metoda >0, mute!.loc,() este executat in >0, dar firul apelant nu este blocat dinmoment ce de(a detine mute!-ul. 'aca mute! ar fi fost un semafor binar in loc de zavor, apelul
de la 0 la >0 ar fi blocat firul apelant cand mute!.P() era executat in >0. Amintitiva ca
terminarea operatiilor !0 si %0 intr-un semafor binar trebuie sa alterneze.0 Aceasta ar crea osituatie de deadloc) din moment ce nici un alt fir nu poate fi executat in cadrul lui >0 sau 0.
=xista cateva diferente intre zavoare si semafoare binare7
• !entru un semafor binar, daca sunt facute doua apeluri la !0 fara interventia unui apel la
%0, al doilea apel va bloca. 'ar un fir care detine un zavor si trimite o cerere de detineredin nou nu este blocat. atentie deoarece zavoare-le nu sunt intotdeauna recursive, deci
consultati documentatia inainte de a folosi un zavor.0
• 'etinatorul pentru apelurile succesive la loc,() si unloc,() trebuie sa fie acelasi fir. 'ar
apelurile succesive la !0 si %0 pot fi facute de fire diferite.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
'in moment ce zavoarele sunt mai flexibile cand vorbim de apelarea metodelor, vom folosi
deobicei zavoare in loc de semafoare pentru a crea obiecte blocabile. /u toate acestea vom
intampina situatii unde nu este posibila folosirea zavoare-lor fara violarea restrictiilor privinddetinerea. In aceste situatii, folosim semafoare binare sau numaratoare.
1raducere /apitolul 3.H7
Implementare Semafoare7
!roblema Semafoarelor poate fi implementata la nivel utilizator, la nivelul sistemului de
operare,sau cu suport "ardFare. 2u exista sisteme de operare sau limba(e de programare care sa
suporte reluarea programului prin semafoare. In aceasta sectiune vom discuta despre cum sa
implementam semafoare. <ai tarziu vom prezenta implementari ale semafoarelor la nivel
utilizator in limba(ul Java si /;;:Win3:!t"reads. 'e asemenea vom arata cum acesteimplementari pot fi extinse pentru a suporta urmarirea executiei si reluarea acesteia, si o te"nica
interesanta de testare.
3.H.#
Implementarea !0 si %0
!unctele 3.3 si 3.H arata cateva posibile implementari ale operatiilor realizate de !0 si %0.
Aceste implementari ilustreaza mecanisme variate pentru blocare si deblocare firelor de executie.
Implementarile # si in Cistingul 3.3 sunt pentru operatiile de numarare ale semafoarelor !0 si
%0. Aceste implementari difera in functie de cum manipuleaza operatia Fait, in !05
Implementarea # foloseste ocupat-asteptand pentru a intarsia firele de executie. /and un fir de
executie in asteptare este activate in !0, el trebuie sa reverifice valorile permisiunilor. = posibil
ca un fir de executie activ va gasi mereu o valoare a permisiunilor egala cu 9 si deci nu va fi
permis niciodata ca !0 sa isi termine operatia. Semafoarele cu astfel de implementare se numesc
semafoare slabe.
Implementarea bloc"eaza firele de executie in asteptare intr-o coada pana cand acestea sunt
c"emate. Klocand firele de executie evitam ca /!$ sa consume cicluri, dar necesita suport de la
limba(ul de programare sau sistemul de operare. /and un fir de executie blocat in !0 este activat
de o operatie din %0 , firului de executie ii va fi permis sa isi executa operatia !0. Aceasta
implementeaza un semafor puternic.
I<!C=<=21AD=A # >BCBS=S1= B/$!A1-AS1=!1A2'
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
Alte solutii la problema critica pot fi folosite in implementarea operatiilor !0 si %0 daca acestea
sunt disponibile.
Java ofera o solutie ce este similara cu blocarea mutex mentionata in sectiunea 3.3.
Kloca(ele Java sunt folosite in implementarile Java de semafoare prezentate in Sectiune 3.+.Implemetarile semafoarele ce au fost prezentate pana acum pot fi implementate la nivel
utilizator. Semafoarele pot fi implementate si la nivel sMstem de operare. Cisting 3. arata
implemetarea operatiilor !0 si %0 ca operatii in nucleul sistemului de operare. Sunt create
sectiuni critice activand si dezactivand intreruperi. !entru o masina multi processor cu s"ared
memorM, dezactivarea intreruperilor poate sa nu functioneze, asa ca instructiuni "ardFare
atomice ca cele descries in Sectiunea .3 pot fi folosite. &AndreFs 999 descrie cum se
implementeaza semafoare in nucleul sistemului de operare.
3.$.2
VP'( Ope%&!i)"
B operatie semafor in plus pe care o folosim in aceasta carte este operatia %!0.
In loc sa scriem7
s.%05 t.!05
!s07 disable interrupts5
permits 4 permits - #5
if permits L 90
add t"e calling t"read to t"e Nueue for s and c"ange its state to bloc)ed5
sc"edule anot"er t"read5
6
enable interrupts5
%s07 disable interrupts5
permits 4 permits ; #5
if permits L4 90
select a t"read from t"e Nueue for s5 c"ange t"e t"readOs state to readM5
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
/elelate doua c"emari ale clasei test0 pe care le face filozoful I sunt facute pentru a
debloca vecinii carora le este foame si sunt capabili si manance dupa ce filozoful i termina de
mancat.
3.*.$ ,i!i!)%i i S%ii!)%i
'atele sunt puse in comun de multiple fire de executie. /and un fir de executie citestescrie0
datele puse in comun , este considerat a fi un cititorscriitor0.
/ititorii pot accesa datele puse in comun in mod concurrent, dar un scriitor are intotdeauna acces
exclusiv. 1abela 3.# arata sase strategii diferite pentru a controla cum cititorii si scriitorii primesc
prioritate cand ambii doresc sa acceseze in acelasi timp datele puse in comun.
#. D4W scriitorii si cititorii au prioritate egala si sunt serviti impreuna dupa metoda
>/>Sprimul venit primul servit0. D8W cititorii au in general prioritate mai mare decat scriitorii
3. DLW cititorii au in general prioritate mai mica decat scriitorii<ai multe strategii exista pentru fiecare categorie datorita sc"imbarilor de prioritati in situatii
specifice.
TABLE 3.1
A,,ES STRATE+; DES,RIPTION
D4W.#$n cititor sau un scriitor cu prioritate egala.
D4W <ai multi cititori sau un scriitor cu prioritate egala
D8W# <ai multi cititori sau un scriitor5 scriitori au prioritate mai mare D8W
Ca fel ca D8W# cu exeptia ca atunci cand soseste un cititor, daca
nici un alt cititor nu citeste sau asteapta, se asteapta pana cand
toti scriitorii care au sosit mai devreme au terminat
DLW# <ai multi cititori sau un scriitor cu scriitorul avand prioritate mai
mare
DLW Ca fel ca DLW# cu exeptia ca atunci cand soseste un scriitor, daca
nici un alt scriitor nu scrie sau asteapta, se asteapta pana cand
toti cititorii care au sosit mai devreme au terminat
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
Ca sfarsitul operatiei de scriere , cititorii in asteptare au prioritate. 'aca cititorii asteapta in
readersXNue , unul dintre ei este semnalat. Acest prim cititor verifica daca vreun alt cititor asteapta. 'aca se intampla asa, atunci anunta al doilea cititor, ce il anunta pe al treilea, si tot asa.
Aceasta notificare in cascada continua pana cand nici un cititor nu mai asteapta. 'aca nici un
cititor nu asteapta cand a terminat un scriitor, este notificat un scriitor.
Aceasta implementare ilustreaza un alt model important de semafor, numit passing-t"e-
baton. Aveti in vedere ca cititorii intarziati si scriitorii, ies din sectiunile lor critice inainte de a se
bloca singuri in readersXNue.!0 sau FritersXNue.!0. Aceasta e parte din modelul iesi inainte de a
astepta mentionat mai devreme.
int activeDeaders 4 95 :: number of active readers
int activeWriters 4 95 :: number of active Friters
int FaitingWriters 4 95 :: number of Faiting Friters
int FaitingDeaders 4 95 :: number of Faiting readers
FritersXrXNue.%05 :: signal lead reader or a Friter at t"e front of t"e Nueue
6
Li!i"# 3.12 StrategM D &W..
Aceasta solutie este interesanta deoarece incalca modelul iesi inainte de a astepta descries mai
devreme. /a o regula un fir de executie va iesi dintr-o sectiune critica inainte sa se bloc"eze
singur intr-o operatie !0. Bricum cititorii lideri incalca aceasta regulacand executa
FriterXrXNue.!0 fara a executa mai inainte mutex.%0 pentru a iesi din sectiunea critica. Aceasta
este c"eia solutiei. 'oar un cititor lider exemplu7 cand activeDeader44#0 pot intra in coada
pentru FritersXrXNue.%0,pe cand toti ceilalti scriitori sunt blocati de mutex.!0 la inceputul
operatiei de citire. /and cititorul lider este eliberat de FritersXrXNue.%0,cititorul lider permite
celorlalti cititori sa intre in sectiunea critica notificand mutex.%0. /eilalti cititori nu vor executa
FritersXrXNue.!0cand activeDeaders44# este adevarat doar pentru cititorul lider.
DLW7
Aceasta strategie permite citirea concurenta si in general da scriitorilor o mai mare prioritate
decat cititorilor. /ititorii au permisiune in urmatoarea situatie7
/and un scriitor cere sa scrie, daca este un scriitor lider exemplu7 nici un alt scriitor nu scrie saunu asteapta sa scrie0 asteapta pana cand toti cititorii care au sosit mai devreme au terminat de
citit.
Aceasta strategie si strategia D8W. sunt simetrice. Solutia din listingul 3.#3 pentru DLW.
difera fata de solutia din listingul 3.# pentru D8W. cu urmatoarele7
Semaforul readersXFXNue este folosit pentru a permite unui scriitor lider sa bloc"eze
cititorii. 'oar un scriitorun scriitor lider0 poate fi blocat in aceasta coada.
Semaforul FritersXrXNue e redenumit FritersXNue, deoarece cititorii nu sunt niciodata
blocati in aceasta coada.
%ariabila FaitingBrWritingWriters e folosita pentru a numara numarul scriitorilor ce
asteapta sau scriu.
/and un Scriitor W executa Write07
'aca unul sau mai multi scriitori asteapta ca cititorii sa termine, W e blocat in mutexXF5
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
'aca nici un alt scriitor nu scrie sau nu asteapta, W este un scriitor lider, asa ca W executa
readersXFXNue.!0. 'aca un cititor citeste, W va fi blocat in readersXFXNue in spatele oricarui
cititor care asteapta5 altfel W poate incepe sa scrie si cititorii vor fi blocati cand vor executa
readersXFXNue.!0.
W poate fi urmat de mai multi scriitori. /and ultimul dintre acesti scriitori termina elexecuta readersXFXNue.%0pentru a notifica cititorii. 'aca un scriitor care a terminat observa ca
un alt scriitor asteapta, cititorii vor infometa.
>olosirea readersXFXNue asigura ca cititorii care au a(uns inaintea scriitorului lider au prioritate
mai mare. Asta deoarece cititorii si scriitorul lider amandoi c"eama readersXFXNue.!0, si acestia
sunt serviti in ordinea >/>S. /and un cititor blocat in readersXFXNue ii este permis sa citeasca el
executa readersXFXNue.%0 pentru a notifica urmatorul cititor ce asteapta pentru a executa
readersXFXNue.%0, si tot asa. Aceasta notificare in cascada continua pana cand nu mai existacititori care asteapta sau pana cand operatia readersXFXNue.!0 notifica un scriitor lider.
Scriitorul lider executa FritersXNue.!0 pentru a se bloca singur pana cand ceilalti cititori termina
de citit.
3.*.*
Simularea semafoarelor ce numara
!resupunem ca un sistem ofera semafoare binare dar nu semafoare numaratoare.
Cistingul 3.#H arata cum se folosesc semafoarele binare pentru a implementa operatiiile !0 si %0
in clasa countingSemap"ores.
int activeDeaders 4 95 :: number of active readers
int FaitingBrWritingWriters 4 95 :: number of Friters Faiting or Friting
mutexCoc) mutexXr 4 neF mutexCoc)05 :: exclusion for active:eaders
-operatiile semafoarelor urmeaza o conventie diferita de raportare a erorilor. =le returneaza zero
in caz de succes. In caz de esec, ele intorc valoarea -# si memoreaza numarul corespunzator
erorii in errno.>olosim functia / perrorconst c"arE string0 pentru a transcrie valoarea lui errno
intr-un sir si a afisa acel sir in stderr.
-=xista o operatie conditional de asteptare sem tr>wait sem tE sem0 care nu va bloca niciodata
firul de executie invocator. 'aca valoarea semaforului este mai mare de zero,valoarea este
decrementata si operatia se intoarce imediat .Altfel spus,operatia intoarce imediat codul de eroare
=AAI2 indicand ca valoarea semaforului nu a fost mai mare ca zero.
Cista 3. arata cum obiectele semafor !t"reads sunt folosite. >isierul "eader Lsemap"ore."8
trebuie sa fie inclus pentru a folosi operatiile semafoarelor.Semafoarele apartin tipului tMpe
semXt.$n semafor este creat prin invocarea functiei semXinit0.!rimul argument este adresa
semaforului.'aca al doilea argument are o valoare diferita de zero ,semaforul poate fi impartitintre procese./u o valoare egala cu zero,poate fi impartit de firele de executie ale aceluiasi
proces.Al treilea argument este valoarea initiala.Acdn semaforul nu mai ese necesar,este distrus
prin invocarea functiei semXdestroM0.
!utem crea o clasa simpla in /;; care impac"eteaza semafoarele !BSI[,asa cum am facut si cu
!BSI[Semap"ore invoca mai departe functiile corespunzatoare ale semaforului !BSI[.!entru a
testa si depana,vom avea nevoie de o incuietoare de nivel utilizator si clase semafor de tipul celor
pe care le-am dezvoltat pentru Win3.!utem folosi P0S#?Semaphore pentru a implementa
ambele clase./odul pentru /;;:!t"reads
Al claselor mute!-oc, si countingSemaphore este identic cu cel din lista 3.3 si 3.H,exceptiefacand faptul urmator7clasa Fin3Semap"ore ar trebui inlocuita de clasa
!BSI[Semap"ore.'iferenta dintre Win3 si !BSI[ este incapsulata in clasele semafor.
garantie ne permite noua sa ignoram problemele consistentei memoriei parta(ate atunci cand
folosim incuietori sau semafoare pentru a crea sectiuni critice in programul nostru.'in acest
motiv,ne propunem regula de a accesa variabilele parta(ate in interiorul sectiunilor critice.In
continuare vom vedea ca aceasta regula de aemenea simplifica testarea si depanarea.
3.#9 $rmarirea,testarea si reluarea pentru semafoare si incuietori.
In aceasta sectiune adresam doua probleme de testare si depanare pentru programe care folosesc
semafoare si incuietori.Intai,descriem o te"nica speciala de testare pentru detectarea incalcarii
excluderii mutuale.Apoi vom arata cum sa urmariti si sa reluati executiile programelor in timpul
depanarii.
3.#9. 1estarea nondeterminista cu algoritmul Coc)set
$n program concurent care foloseste semafoare si incuietori poate fi testat pentru cursele de
date.Amintiti-va din capitolul # ca o cursa de date este un esec in implementarea corecta a
sectiunilor critice pentru accesarea variabilelor nonatomice parta(ate.Abordarea pe care o vom
folosi pentru a detecta cursele de date este de a monitoriza accesarile variabilelor parta(ate si de ane asigura ca fiecare variabile a fost corespunzator incuiata inainte de a fi accesata.'e vreme ce
executiile programului sunt nedeterministice ,va trebui sa executam programul de cateva ori cu
aceeasi intrare de test pentru a creste sansele de a gasi curse de date.Acest tip de testare se
numeste testare nondeterminista.
1estarea nondeterminista a uni program concurent /! implica urmatorii pasi7
#.Selectarea unui set de intrari pentru /!
.!entru fiecare intrare [ selectata,executam /p cu [ de mai multe ori si examinam rezultatul
fiecarei executii.
=xecutiile multiple nondeterministe ale /! cu [ intrari exercita diferite comportamente ale /! si
astfel putem detecta mai multe esecuri decat o singura executie a /! cu intarea [.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
Scopul testarii nondeterministe este acela de a detecta cat mai multe comportamente posibile
distincte ale programului .'in nefericire,experimentele au aratat ca executia repetata a unui
program concurent nu conduce la executarea comportamentelor diferite.In absenta variatiilor
semnificative ale intarzierilor I:B sau ale intarzierilor de retea,sau sc"imbari semnificative in
incarcarea programului,programele tind sa arate acelasi comportament de la executie la
executie.<ai mult,efectul de proba,care apare cand programele sunt instrumentate cu cod de
depanare,pot face posibila observarea unor esecuri.
=xista cateva te"nici pe care le putem folosi pentru a creste probabilitatea exercizarii
comportamentelor diferite.$nul este sa sc"imbam algoritmul de planificare al sistemului de
operare.Insa,in multe dintre sistemele de operare comerciale acest lucru nu este posibil.A doua
te"nica este de a insera declaratii Sleept0 in program cu cantitatea de somn t aleasa la
intamplare.=xecutarea unei declaratii Sleept0 forteaza o sc"imbare de context si apoi indirect
afecteaza planificarea firelor de executie.Am implementat aceasta a doua te"nica ca o optiune de
executare pentru programele care folosesc binar>Semaphore countingSemaphore, si clase
mute!-oc, in libraria noastra de sincronizare./and optiunea aceasta este specificata ,declaratiile
Spleep sunt executate la inceputul metodelor !0, %0, si unloc)0.1impul cat dureaza Sleep este
ales intamplator cu o gama programabila.Intarzierile aleatoare pot fi folosite in con(unctie cu
functiile de urmarire si reluare pentru ca fiecare eroare observata sa poate fi de asemenea reluata.
!entru a detecta curse de date,combinam testarea nondeterminista cu algoritmul loc)set.Acest
algoritm verifica ca toate variabilele parta(ate sa urmeze o disciplina a inc"iderii consistenta in
care fiecare variabila parta(ata este prote(ata de o incuietoare.'e vreme ce nu se cunoaste ce
incuietoare va inc"ide fiecare variabila,trebuie sa urmarim executiile si sa incercam sa deducem
o relatie intre incuietori si variabile.!entru fiecare variabila,determinam daca este vreo
incuietoare care este mereu tinuta oricand variabila este accesata.
!entru variabilele parta(ate v,lasam ca setul *andidate-oc,s(v) sa fie acele incuietori care au
prote(at v in timpul executiilor de pana acum.Astfel,o incuietoare l este in *andidate-oc,s(v)
dacain timpul executiei de pana acum,fiecare fir de executie care a accesat v tinea l la momentul
accesarii. *andidate-oc,s(v) este calculat astel"
-cand o noua variabila v este initializata,setul ei de candidati este considerat ca tine toate
incuietorile posibile.
-cand v este accesat pe o operatie de citire sau scriere de 1, *andidate-oc,s(v) esteredefinit.2oua valoare a lui *andidate-oc,s(v) este intersectia dintre *andidate-oc,s(v) si setul
de incuietori retinut de firul 1.
Kazandu-ne pe acest algoritm de rafinare,daca anumite incuietori l prote(eaza consistent v,vor
ramane in *andidate-oc,s(v) pe masura ce *andidate-oc,s(v) este rafinat.'aca
*andidate-oc,s(v) devine gol,el indica ca nu exista nici o incuietoare care prote(eaza v
consistent.<ai (os este algoritmul loc)set7
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
siguranta ignorat,algoritmul loc)set poate fi oprit pentru aceste variabile.Alternativ,tamponul
poate fi implementat folosind s"ared%ariable.
Algoritmul loc)set a fost initial implementat intr-un instrument de testare numit =raser.'e
asemenea a fost implementat ca parte a unei masini virtuale de (ava,numita Java
Apt"finder.Algoritmul loc)set s-a dovedit a fi o te"nica practica de detectare a curselor de date in programe care prote(eaza variabilele parta(ate cu incuietori.Bricum,programele care folosesc
semafoare pentru excluziunea mutuala ,cu sabloane ca passingXt"eXbatton,vor genera alarme
false.Asa cum s-a aratat mai sus pentru programul tamponului delimitat ,loc)set poate da alarme
false c"iar si daca sunt folosite incuietori.2umarul de alarme false poate fi diminuat daca li se
permite utilizatorilor sa inc"ida algoritmul de detectie pentru regiuni de cod sau sa TI asigure
algoritmului de detectie informatii suplimentare./a o te"nica de testare
nondeterminista,algorimul loc)set nu poate dovedi ca un program nu contine curse de date.In
orice caz,stiind ca o anume executie nu contine curse de date poate fi de a(utor in timpul
urmaririi si reluarii ,asa cum vom vedea mai incolo.
3.#9. Secvente S]2 simple pentru semafoare si incuietori.
In general putem caracteriza o executie a unui program concurent ca o secventa de evenimente
sincronizate a unor obiecte sincronizate.B secventa a unor evenimente sincronizate se numeste
secventa S]2.<ai intai definim tipul evenimentelor sincronizate si apoi obiectele sincronizate
care apar in programele ce contin semafoare si incuietori.Acesti doi pasi nu sunt
independenti.Sunt cateva moduri de definire a unei secvente S]2,si definitia unei secvente S]2
are efect asupra proiectarii solutiei de reluare,si viceversa.
Casati /! sa fie un program concurent ce foloseste variabile parta(ate,semafoare si
incuietori.Dezultatul executarii uni /! cu o intrare data depinde de ordinea in care variabilele
parta(ate,semafoarele si incuietorile in /! sunt accesate.Semafoarele sunt accesate folosind
operatii ! si %,incuietorile sunt folosite folosind operatii loc) si unloc),iar variabilele parta(ate
sunt accesate folosind operatii de citire si scriere.Insa,evenimentele sincronizate in /! sunt
executii de read:Frite, !:% si loc):unloc) ale acestor obiecte.
Am aratat ca pot fi variabile parta(ate ce pot fi accesate in implementarile operatiilor !:% sau
loc):unloc).'e fapt,aceste variabile parta(ate pot fi accesate de foarte multe ori,din cauza
buclelor de asteptare ocupate.Insa,nu vom urmari operatiile de citire si scriere pe aceste variabile
parta(ate.'e vreme ce !:% si loc):unloc) sunt operatii atomice ,le vom considera ca operand pe
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
-startul unei operatii unloc) care nu este niciodata inc"eiata din cauza unui punct mort sau a unei
exceptii
2e referim la o astfel de secventa ca la o secventa Coc)$nloc) de l.$n eveniment intr-o secventaCoc)$nloc) este denotat de identificatorul firului de executie care a executat operatia loc) sau
unloc).!entru a ilustra aceste definitii ,consideram programul simplu din lista 3.3#.%aloarea
finala a variabilei parta(ate x este # sau .B posibila secventa DeadWrite a variabilei parta(ate x
este7
Asta inseamna ca x a fost mai intai accesata de 1"read# si apoi de 1"read.'e vreme ce 1"read#
a accesat prima data pe x,secventa !% pentru mutex trebuie sa indice ca 1"read# a efectuat
operatiile ! si % inaintea lui 1"read.A doua operatii ! in 1"read este o eroare.Aceasta operatie
! va incepe dar nu se va sfarsi si ar trebui sa fie o operatie % in locul ei.
B secventa S]2 pentru un program concurent /! este o colectie de secvente
DeadWrite,secvente !% si secvente Coc)$nloc).=xista o singura secventa pentru fiecare dintre
variabile,semafor sau incuietoare in program.B secventa S]2 pentru program in lista 3.3#
contine o secventa DeadWrite pentru x si o secventa !% pentru mutex7
Secventa DeadWrite a lui !7 #, 9, 90, , #, 905secventa !% a mute!7 #, #, , 00.
Aceasta este o ordonare partiala a evenimentelor sincronizate in program.Asta inseamna ca
evenimentele pe un singur obiect sunt total ordonate,dar ordinea evenimentelor din mai multe
obiecte diferite nu este specificata.Alternativ,putem defini o secventa S]2 a unui program ca o
secventa singulara total ordonata de evenimente sinconizate peste toate obiectele sincronizate.o
secventa total ordonata de evenimente care este consistenta cu partial ordonata secventa de mai
sus este 7
#, #, 9, 90, #, , , #, 90, .
In general,pot fi doua sau mai multe secvente total ordonate care sunt consistente cu o ordine
partiala data de vreme ce doua evenimente concurente pot aparea in ordonarea totala in alta
ordine.
'efinitia unei secvente S]2 are intentia de a captura ce inseamna pentru o executie sa reia o
alta.!resupunem ca atunci cand programul de mai sus este executat ,1"read executa mutex.!0
si se bloc"eaza deoarece 1"read# este de(a in sectiunea critica.In timpul reluarii acestei
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
Bbservatia noastra despre sectiunile critice nu duce la o solutie mai buna de reluare.>ace,insa,sa
mareasca importanta excluziunii mutuale si nevoia de constructii sincronizate care sunt necesare
in implementarea corecta a excluziunii mutuale./onstructorul monitor din capitolul H este o
asemenea constructie.>olosirea monitorului imbunatateste ma(or sansele ca variabilele parta(ate
sa fie accesate in interiorul sectiunii critice si realizeaza mai usor executia de reluare.
<omentan,vom incerca sa imbunatatim solutia de reluare prin folosirea algoritmului loc)set in
paralel cu reluarea.In timpul reluarii,presupunem ca variabilele parta(ate sunt accesate in
interiorul sectiunilor critice care sunt implementate cu mutexCoc)s folosite ca incuietori.Asta ne
permite sa ignoram operatiile de scriere si citire asupra variabilelor parta(ate.In timpul
urmaririi,vom folosi algoritmul loc)set pentru a ne valida presupunerea.algoritmul loc)set ne va
spune cand reluarea poate esua.
Asa cum am mentionat anterior,in cazul in care o variabila parta(ata poate fi accesata in siguranta
in afara sectiunii critice,algoritmul loc)set poate fi inc"is pentru acea variabila,astfel incat sa nu
produca un avertisment.In orice caz,asta poate crea o problema pentru reluare deoarecedepindem de fiecare variabila parta(ata sa fie accesata in interiorul sectiunii criticF ,astfel incat
accesul fiecarei variabile parta(ate sa fie reprezentat de operatiile loc)0 sau !0 in urmarirea
executiei.In aceste cazuri,incuietorile pot fi folosite pentru a crea sectiuni critice ,cel putin
temporar,astfel incat reluarea sa poata fi facuta.!roiectarea unui program pentru a fi mai usor de
testat si depanat creste testabilitatea programului.
Casati un /! sa fie un program concurent ce contine incuietori mutex,semafoare binare si
semafoare de numarare.!resupuneti ca variabilele parta(ate sunt accesate corect in interirulsectiunii critice7
-fiecare semafor si incuietoare in /! este un obiect de sincronizare
-evenimentele de sincronizare intr-o secventa !% simpla pentru un semafor sunt patru tipuri de
evenimente definite mai sus
-evenimentele de sincronizare intr-o simpla secventa Coc)$nloc) pentru o incuietoare mutex
sunt patru tipuri de evenimente descrise mai sus
-fiecare eveniment de sincronizare este denotat de identificatorul firului de executie care a
exucutat evenimentul.
!entru a relua executia unui /! trebuie sa reluam secventele !% pentru semafoarele din /! si
secvntele simple Coc)$nloc) pentru incuietorile din /!.In urmatoarea sectiune va vom arata
cum sa faceti asta.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
!resupunem ca imlemantarile lui !0 si %0 contin sectiuni critice pentru accesarea variabilelor pe
care le parta(eaza.Am indicat asta prin intermediul comentariilor cu privire la operatiile inc"ide
si desc"ide cre creaza aceste sectiuni critice.Invocarea re9uestPermit() releasePermit()
trace*ompleteP(), si trace*ompleteV() trebuie sa fie pozitionate corect in conformitate cu
sectiunile critice in !0 si %0.Invocarea reNuest!ermit0 apare inainte de operatia de inc"idereiar invocarea release!ermit0 apare imediat dupa operatia de inc"idere.Invocarea
trace*ompleteP() si trace*ompleteV() apare in interiorul sectiunii crtice.Asta asigura ca
evenimentele sunt inregistrate in timpul urmaririi executiei in ordinea in care ele apar.'aca
invocarea functiei trace este facuta in afara sectiunii critice,ordinea invocarilor poate sa nu fie
consistenta cu ordinea in care firele de executie si-au completat operatiile !0 si %0.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta
<odificarea metodelor loc)0 si unloc)0 7 Implementarile metodelor loc)0 si unloc)0 in clasa
mutexCoc) sunt modificate exact ca metodele !0 si %0./lasa mutexCoc) contine referinte la
re9uestPermit() si releasePermit() inainte si dupa operatia de inc"idere din
mutexCoc).Deferintele la trace*omplete-oc,() si
trace*ompletenloc,() apar la sfarsitul sectiunii critice respective.
!entru simplificarea urmaririi si reluarii, nu vom urmari evenimentele care reprezinta startul lui
!,%, loc) sau unloc) care nu s-au completat niciodata din cauza unui punct mort sau a unei
exceptii.1otusi,cand operatiile de producere a unui punct mort sunt reluate,invocarea firelor de
executie nu va fi blocata in interiorul corpului oparatiei5din potriva ele vor fi blocate pentru
totdeauna la invocarea reNuest!ermit0 dinaintea operatiei.'evreme ce in ambele cazuri firul de
executie va fi blocat pentru totdeauna,efectul reluarii este acelasi.Similar,evenimentele care
implica exceptiile ce apar in timpul executiei operatiilor !,%,loc) sau unloc) nu vor fi reluate.'ar
urma va indica ca excutia acestor operatii va ridica o eroare,care probabil asigura a(utor destul
pentru depanarea programului.Solutia nostra poate fi extisa astfel incat evenimentele incomplete
sunt de fapt executate.
/ontrolul /lasei7 >iecare semafor si incuietoare este asociat cu un obiect de control.In modul de
reluare, obiectul de control introduce secventa S]2 a semaforului sau incuietorii si se ocupa de
invocarea reNuest!ermit 0 si release!ermit0.In modul de urmarire obiectele de controlcolecteaza evenimentele sincronizate care apar si le inregistreaza intr-un fisier de urmarire./and
un fir de executie invoca reNuest!ermit0 sau una dintre metodele de urmarire isi prezinta
identificatorul id.!resupunem ca toate firele de executie sunt instantieri ale clasei %B%hread
.Aceasta clasa se ocupa de crearea unor id-uri unice pentru firele de executie.
B clasa de control /;; este aratata in lista 3.3./onsideram un semafor s si o secventa simpla
!% pentru s care a fost inregistrata in timpul unei executii anterioare./and obiectul de control
pentru s este creat, el citeste secventa pv simple pentru s intr-un vector
S]2seNuence.!resupunem ca prima operatie (-#,(89 a fost completata si valoarea lui
S]2seNuence(0 este ), asta inseamna ca firul de executie 1)0 trebuie sa execute urmatorul
eveniment./and firul de executie 1(0 invoca metoda reNuest!ermit0 este blocat prin executia lui
1i0.
7/23/2019 Modern_Multithreading Semafoare Si Zavoare Versiune Beta