Sunteți pe pagina 1din 6

12

4.4. Sincronizarea taskurilor pe o condiţie de timp. Reprogramarea execuţiei taskurilor


Pentru realizarea sincronizării taskurilor pe o condiţie de timp se pot crea trei tipuri de
directive:
1. AŞTEAPTĂ(interval de timp t)
2. MARCHEAZĂ( interval de timp t, variabilă eveniment EV )
3. REPROGRAMEAZĂ( număr (nume) task NRTASK, interval de timp t )

1.Primitiva AŞTEAPTĂ( t) are efect numai asupra taskului care a lansat-o, presupunând din
partea EXECUTIVULUI următoarele acţiuni neîntreruptibile:
- înscriera valorii t într-un contor local aferent taskului;
- blocarea taskului până la expirarea intervalului de timp t;
- decrementarea contorului cu o cuantă de timp la fiecare întrerupere dată de ceasul de timp
real;
- trecerea taskului în starea READY la anularea contorului şi declararea de eveniment
semnificativ.
Din punct de vedere al evoluţiei programului, dacă taskul lucrează în buclă infinită, modul de
sincronizare realizat de această directivă este prezentat în Figura 5.7.
t  t  t 
0
Timp
Interval de timp de execuţie a taskului
Interval de timp de aşteptare
Fig.5.7.
Se observă că intervalul de timp de reprogramare a execuţiei taskului este t+ cu 
variabil deoarece nu este cunoscut momentul intrării în execuţie a taskului şi nici durata execuţiei
lui.
Observaţie: La expirarea intervalului de timp t, taskul este trecut în starea READY urmând să fie
adus în execuţie de către EXECUTIV funcţie de procedeul ales pentru planificarea taskurilor pentru
execuţie). Acest mod de sincronizare a execuţiei unui task poate fi satisfăcător numai dacă   t .
În caz contrar, intervalul de timp de reprogramare a execuţiei taskului nu mai poate fi
evaluat.
În aplicaţiile practice se doreşte însă ca intervalul de reprogramare a execuţiei unui task să
fie cunoscut şi să aibă valoarea t, specificată ca parametru în directivă. Altfel spus, se doreşte o
sincronizare de tipul celei arătate în Fig.4.6.

t t t
0
   Timp

Interval de timp de aşteptare


Interval de timp de execuţie a taskului
Fig.4.6.
Utilizând directiva AŞTEAPTĂ(t) o astfel de evoluţie se poate obţine introducând în
aplicaţie un task suplimentar numit task planificator şi utilizând o variabilă eveniment EVS având
valoarea iniţială FALS. Structura celor două taskuri (planificator şi reprogramat) este prezentată în
Fig.4.7, iar diagrama de lucru este cea din Fig.4.8.

35
Task Task
PLANIFICATOR

Secventă de iniţializare Secvenţă de iniţializare

A§TEAPTĂ (t ) A§TEAPTĂ (EVS)


CONSUMĂ (EVS)
DECLANŞEAZĂ (EVS)
Secvenţă de program executată
ciclic
Fig.4.7.

t t t
0
  Timp

Interval de timp de aşteptare a


Fig.4.8. taskului REPROGRAMAT
Interval de timp de execuţie a
taskului REPROGRAMAT
Interval de timp de reprogramare

Deşi se pierde un interval de timpt la pornirea aplicaţiei (momentul 0) şi deşi nu se


cunoaşte exact momentul intrării în execuţie a taskului şi nici durata execuţiei sale, evoluţia este
satisfăcătoare dacă suntem siguri că execuţia taskului REPROGRAMAT are loc în intervalul
de timp t, adică   t .
13 2.Primitiva MARCHEAZĂ (t, EV) deşi are efect tot numai asupra taskului care o
lansează, prezintă avantaje şi facilităţi în privinţa realizării sincronizării dorite conform diagramei
din Figura 5.8. Această primitivă presupune efectuarea din partea EXECUTIVULUI a următoarelor
acţiuni neîntreruptibile:
- înscriera valorii t într-un contor local aferent taskului;
- ştergerea variabilei eveniment EV (EV devine FALS);
- decrementarea contorului cu o cuantă de timp la fiecare întrerupere dată de ceasul de timp
real;
- setarea variabilei eveniment EV (EV devine ADEVĂRAT) la anularea contorului şi
declararea de eveniment semnificativ.
De remarcat este faptul că în urma apelării acestei directive, taskul nu se blochează, ci îşi va
continua execuţia până va întâlni şi va lansa directiva AŞTEAPTĂ(EV). Dacă în acest
moment intervalul de timp t nu expirase, taskul se va bloca până la expirarea acestui interval de
timp, când variabila eveniment EV va fi setată şi taskul va trece în starea READY.
Structura programului unui task reprogramat prin intermediul acestei directive este
prezentată în Fig.4.9, iar diagrama de lucru este cea din Fig.4.6

36
Task REPROGRAMAT
Secvenţă de iniţializare

MARCHEAZĂ( t, EV )

Secvenţă de program
executată ciclic

AŞTEAPTĂ(EV) Fig.4.9

Avantajul acestei structuri este acela că nu mai este nevoie de un task suplimentar, ca în cazul
anterior, şi nu se mai pierde primul interval de reprogramare.

14 3.Primitiva REPROGRAMEAZĂ t) are efect asupra taskului al cărui


număr sau nume este specificat ca parametru în directivă. Acest task poate fi chiar taskul
care apelează directiva sau oricare alt task component al aplicaţiei. În cazul în care taskul menţionat
în directivă este chiar taskul apelant, sincronizarea funcţionării se realizează conform schemei din
Fig.4.5., iar când taskul menţionat este altul decât taskul apelant, sincronizarea funcţionării se
realizează conform schemei din Fig.4.8. Acest din urmă caz presupune existenţa fie a unui task
suplimentar care să efectueze reprogramarea tuturor taskurilor constituente ale aplicaţiei, sau
reprogramarea să se facă în secvenţa de iniţializare a taskului (care se execută o singură dată la
pornire). Activitatea EXECUTIVULUI în urma apelării acestei directive este următoarea:
- trece taskul specificat într-o tabelă de ceas aferentă unităţii de timp asociate intervalului de
timp t;
- încarcă valoarea t într-un contor inclus în aceeaşi tabelă;
- blochează taskul până la expirarea intervalului de timp t;
- decrementează contorul cu o cuantă de timp la fiecare întrerupere dată de ceasul de timp
real;
- trece taskul specificat în starea READY la anularea contorului, reînscrie valoarea t în
contor şi declară eveniment semnificativ.
Task pentru iniţializareşi programare Task reprogramat - TR

Secvenþá de iniþializare Secvenþa de iniþializare

REPROGRAMEAZÁ (TR, t)


Secvenþá de program
executatá ciclic
Secvenþá de program
EXIT
Fig. 4.10.
Structura programului unui task reprogramat prin intermediul acestei directive este

37
prezentată în Fig.4.10, iar diagrama de lucru este cea din Fig.4.6.
Observaţie: Pentru anularea reprogramării unui task trebuie creată o primitivă specială,
ANULEAZĂ, având ca parametru numărul sau numele taskului, care determină EXECUTIVUL
să-l scoată din listele de ceas.

154.5. Comunicarea între taskuri


În cazul în care excluderea mutuală şi sincronizarrea taskurilor se realizează prin
intermediul semafoarelor şi a variabilelor eveniment, cel mai eficient mod de a rezolva problema
comunicării între taskuri constă în utilizarea unei zone de memorie accesibilă tuturor taskurilor care
cooperează, numită zonă comună. Această zonă este structurată în funcţie de natura informaţiilor
schimbate şi de regulile care guvernează comunicarea propriu-zisă. Datele comune schimbate între
taskuri poartă denumirea generală de mesaje. Ele sunt transmise de un task numit
task PRODUCĂTOR şi destinate unui alt task numit task CONSUMATOR, care fie că le aşteaptă,
fie că le va găsi în momentul în care are nevoie de ele.
În procesul de comunicare prin intermediul zonelor comune, pot apare două situaţii:
=>1. Mesajul transmis de un task nu are o destinaţie specială, el putând fi consumat de orice alt task
al aplicaţiei. Dacă mesajul nu este consumat între două depuneri succesive, el se va pierde
prin înscriera peste el al unui alt mesaj. În acest caz este nevoie ca taskul consumator să nu poată
extrage un mesaj pe care producătorul este în curs să-l depună, iar taskul depunător să nu poată
depune un mesaj pe care consumatorul este în curs a-l extrage sau, altfel spus, operaţiile de
depunere şi extragere a mesajelor trebuie să se execute în excludere mutuală la nivelul
mesajului. Această condiţie este satisfăcută prin introducerea unui semafor de excludere mutuală
asociat zonei comune, notat ZC. Corespondenţa între două taskuri Ti şi Tj se stabileşte programând
la nivelul fiecăruia următoarele secvenţe de instrucţiuni, Fig. 5.13.

Task Ti (PRODUCĂTOR) Task Tj (CONSUMATOR)

Secvenţă de program
-construire mesaj- Secvenţă de program

P ( ZC ) P ( ZC )

Depune mesajul în zona comună Extrage mesajul din zona comună


(secţiune critică) (Secţiune critică)

V (ZC ) V (ZC)

Secvenţă de program Secvenţă de program dependentă


de mesaj
Figura 4.11
Deci, zonei comune i se asociază semaforul ZC având valoarea iniţială 1. Înainte de
depunerea mesajului, taskul PRODUCĂTOR Ti este obligat să execute primitiva P(ZC) în
urma căreia este exclus accesul la zona comună al oricărui alt task Tj, j ≠ i, iar după depunerea
mesajului este obligat să execute primitiva V(ZC) care eliberează accesul la zona de date comune a
taskurilor consumatoare.

38
=>2. Mesajul este destinat numai unui singur task. În acest caz se creează primitive speciale
de transmitere, respectiv de recepţionare a mesajelor care vor cuprinde pe lângă mesajul
transmis(recepţionat) numele sau numărul taskului transmiţător(consumator), precum şi un
mecanism de sincronizare. Cel mai eficient este ca acest mecanism să fie implicit, adică încorporat
în directive prin intermediul variabilelor eveniment. Aceste primitive sunt de forma:
- TRANSMITE (EV, TASKCONS, MESAJ);
(SEND)
- RECEPTIONEAZĂ (TASKPROD, MESAJ).
(RECEIVE)
Directiva TRANSMITE() este lansată din taskul producător TASKPROD şi presupune
executarea următoarelor acţiuni din partea EXECUTIVULUI:
- setarea variabilei eveniment EV (EV capătă valoarea ADEVĂRAT);
- depunerea mesajului(de regulă de lungime fixă) şi a numelui sau numărului taskului
căruia îi este destinat acest mesaj (TASKCONS) la o adresă MESAJ într-o zonă de
memorie de regulă alocată dinamic.
Directiva RECEPTIONEAZĂ() lansată din taskul consumator TASKCONS testează dacă
la adresa MESAJ este înscris numele sau numărul său şi dacă da, preia mesajul transmis, iar dacă
nu, evoluţia programului, în general, nu mai poate fi controlată. De aceea, pentru o
funcţionare corectă a comunicării între taskuri prin intermediul acestor directive, trebuie realizate
următoarele deziderate:
- taskul producător TASKPROD transmite un mesaj taskului consumator TASKCONS şi nu
trebuie să-i mai transmită un alt mesaj până nu se aigură că acest task a preluat mesajul (adică până
nu i se confirmă recepţionarea lui);
- taskul consumator TASKCONS trebuie să aştepte mesajul transmis de taskul producător
TASKPROD, dacă acesta nu a fost încă transmis, şi să confirme consumarea lui pentru a permite
taskului producător să-i transmită un nou mesaj.
Sincronizarea comunicării celor două taskuri se realizează cu ajutorul variabilelor
eveniment. Cum, de obicei, în orice problemă de transmisie-recepţie mesaje este necesară şi
o sincronizare a comunicării cu o condiţie de timp, în Fig.4.12 este prezentată structura celor două
taskuri care comunică prin intermediul celor două directive TRANSMITE şi RECEPTIONEAZĂ şi
unde sincronizarea cu timpul se realizează prin intermediul unei directive tip
REPROGRAMEAZĂ(NRTASK, t).
Variabilele de sincronizare EV1 şi EV2 au valoarea iniţială FALS. În felul acesta
taskul consumator TASKCONS aşteaptă de fiecare dată pe variabila EV1 până când taskul
producător TASKPROD îi transmite mesajul, la expirarea intervalului de timp t. În
continuare, taskul producător aşteaptă pe variabila eveniment EV2 până îi soseşte confirmarea
(adică variabila EV2 capătă valoarea ADEVĂRAT) că taskul consumator a preluat mesajul şi este
capabil să primească un nou mesaj.
Observaţie: După cum s-a mai arătat, directiva REPROGRAMEAZĂ putea fi lansată şi
dintr-un alt task, eventual un task de iniţializare.

39
Task producător - TASKPROD Task consumator - TASKCONS

Secvenţă de iniţializare
REPROGRAMEAZĂ(TASKPROD, t )
Secvenţă de iniţializare
,

Secvenţă de construire a mesajului AŞTEAPTĂ (EV1)


CONSUMĂ (EV1)
SEND(EV1,TASKCONS,MESAJ)
RECEIVE(TASKPROD, MESAJ)
AŞTEAPTĂ (EV2)
CONSUMĂ (EV2) Secvenţă dependentă de mesaj

EXIT DECLANŞAZÁ (EV2)

Figura 4.12

40