Sunteți pe pagina 1din 18

CAP.4.

SISTEME DE OPERARE ÎN TIMP REAL

Un sistem de operare este o colecţie organizată de programe numite programe de sistem,


care:
a) realizează o interfaţă între utilizator şi sistemul de calcul extinzând setul de operaţii
executate de calculator, minimizând efortul de programare a calculatorului şi optimizând
interacţiunea om-calculator;
b) gestionează resursele calculatorului, în sensul optimizării utilizării lor.
În funcţie de complexitatea sistemului de calcul, programele de sistem se numesc:
- program monitor;
- program executiv;
- program de comandă;
- sistem de operare.
În general, sistemele de calcul mici şi, în special, cele dedicate dispun doar de un monitor
care asigură un minim de servicii utilizatorului, cum ar fi: vizualizarea conţinutului memoriei,
modificarea conţinutului memoriei RAM, vizualizarea conţinutului registrelor şi a indicatorilor
de stare (condiţie) precum şi modificarea valorilor lor, compararea unor zone de memorie etc.
Sistemele de calcul complexe lucrează sub comanda unui sistem de operare.

4.1. Funcţiile unui S.O.


Principalele funcţii asigurate de S.O. actuale sunt:
4.1.1. Funcţia de asistenţă a utilizatorului. Obiectivele urmărite sunt:
a) Furnizarea unui limbaj de comandă care permite introducerea de către utilizator a unor
parametri şi opţiuni pentru utilizarea resurselor fizice şi logice ale sistemului. Realizarea acestei
funcţiuni se face cu ajutorul unui interpreter de comenzi.
b) Furnizarea unor programe (editoare de legături) care realizează legarea diferitelor
module ale unui program sau a mai multor programe de utilizator şi a unor subrutine din
biblioteci de programe într-un singur program executabil. Aceasta permite o mare flexibilitate în
programare, pentru că, diversele module ale programului pot fi iniţial scrise în limbaje diferite,
care să asigure o programare optimă pentru modulul respectiv.
c) Existenţa unor sisteme de gestiune a bibliotecilor de programe destinate înscrierii,
păstrării, actualizării şi eliminării programelor prezente;
d) Furnizarea unui set de macroinstrucţiuni care să permită utilizatorului folosirea în
programele proprii a unor funcţii specifice S.O. (de exemplu subrutine de lucru cu dispozitivele
de I/E).
e) Furnizarea unor programe utilitare pentru editarea programelor de utilizator şi pentru
manipularea informaţiei prezente sub formă de fişiere, programe de copiere a fişierelor etc.
f) Furnizarea unui limbaj de control de tip conversaţional, de dialog între operator şi sistem.
De obicei, S.O. au un limbaj de comandă de tip cu autodocumentare datorită unor puternice
funcţii HELP pe care le au implementate.
4.1.2. Funcţia de asistenţă a execuţiei. S.O. trebuie să permită:
a) Izolarea logică a dispozitivelor defecte şi asigurarea condiţiilor pentru o eventuală
execuţie a lucrărilor cu ajutorul resurselor rămase utilizabile.
b) Testarea automată şi diagnosticarea defectelor.

4-1
c) Afişarea automată a informaţiei de stare.
S.O. sunt dinamice, în sensul că, în permanenţă pot fi adăugate noi funcţii sau rescrise
programele ce realizează funcţii deja implementate.
4.1.3. Funcţia de gestiune. Principala sarcină a unui S.O. este aceea de gestiune a
resurselor sistemului de calcul: unitatea centrală, memoria principală (internă), perifericele de I/E,
bibliotecile şi fişierele de date. Programele pentru gestiune ale unui S.O. pot fi împărţite în 4 mari
categorii:
1) Funcţia de gestiune a memoriei, cu următoarele atribute:
- ţine evidenţa utilizării memoriei, adică permite cunoaşterea în orice moment a zonelor
de memorie libere şi ocupate;
- decide ce proces primeşte memorie, când şi ce cantitate de memorie i se alocă. Alocarea
memoriei se face atât pentru păstrarea programului corespunzător procesului cât şi pentru
necesităţile de execuţie.
- asigură tehnici corespunzătoare de protecţie a memoriei;
- dezalocă resursa când procesul s-a încheiat sau nu mai are nevoie de o anumită cantitate
de memorie.
2) Funcţia de gestiune a procesorului şi proceselor:
- ţine evidenţa procesorului precum şi evidenţa stării proceselor;
- decide prioritatea în utilizarea procesorului, în funcţie de prioritatea lucrărilor ce trebuie
executate;
- planificatorul lucrărilor alocă resursele procesorului necesare realizării unui proces
(lucrare);
- eliberează resursa când procesul nu mai are nevoie de procesor sau când s-a depăşit o
anumită cuantă de timp alocată pentru utilizare.
3) Funcţia de gestiune a dispozitivelor periferice are rolul de a aloca resursele şi a
iniţializa operaţiile de I/E precum şi de a dezaloca aceste resurse când operaţiile de I/E s-au
încheiat.
4) Funcţia de gestiune a informaţiei:
- ţine evidenţa resurselor (fişierelor) şi localizarea acestora pe suporturi magnetice;
- oferă rutinele de acces la informaţie;
- alocă şi dezalocă informaţie prin funcţia de deschidere şi respectiv de închidere a
fişierelor.
Deci, putem spune că:
- funcţia de gestiune trebuie să prevadă funcţiile de control automat prin rutine
specializate asupra tuturor resurselor fizice şi logice ce apar;
- să asigure o cât mai mare independenţă a programelor utilizator faţă de particularităţile
sistemului pe care s-a implementat S.O.;
- să rezolve toate problemele de control al funcţionării sistemului printr-un procedeu
performant de tratare a întreruperilor (utilizarea întreruperilor permite un dialog foarte flexibil
între U.C. şi mediul extern, permiţând semnalarea promptă a diverselor evenimente interne sau
externe);
- să permită modificarea configuraţiei de echipamente periferice, fără ca aceasta să
afecteze programele deja implementate.
Din punct de vedere al utilizatorului, S.O. apare ca o interfaţă între programele sale de
aplicaţii şi echipamentele (elementele) sistemului de calcul, care poate fi reprezentată printr-o
structură ierarhică de forma din Fig. 4.1.

4-2
Se observă că accesul direct la resursele sistemului de calcul este puternic limitat de
existenţa a două nivele intermediare: procesorul de limbaj şi S.O. Fiecare nivel introduce funcţii
noi inexistente la nivelele inferioare definind o maşină virtuală corespunzătoare acelui nivel.

Fig. 4.1.

4.2. Structura sistemelor de operare


Componentele în care se descompune un S.O. sunt situate la diferite nivele ierarhice, având,
de exemplu, structura din Fig. 4.2. Plasarea unei funcţii a S.O. pe unul din cele trei nivele se
realizează pe baza depărtării funcţiei respective de echipamentul fizic. Acest aspect este foarte
evident în toate calculatoarele care folosesc S.O. şi, în special, pentru S.O. scrise în limbaje
evoluate.

S.O. pot fi scrise într-un limbaj de nivel evoluat numai la nivelele superioare, care nu
interacţionează direct cu maşina fizică.
Existenţa nucleului este obligatorie în orice S.O. Nucleul conţine funcţiile privind tratarea
operaţiilor de I/E la nivel fizic, tratarea întreruperilor, tratarea sincronizării şi comunicării între
procese, care sunt scrise, de obicei, în cod maşină sau limbaj de asamblare. Funcţiile care
formează nucleul S.O. sunt intens utilizate de celelalte două nivele superioare şi, din această
cauză, se implementează prin secvenţe de program rezidente în M.O. într-o zonă special rezervată
acestui scop.
Funcţiile de suport pentru execuţia programului sunt apelate în timpul execuţiei unui
program printr-un procedeu asemănător apelului macroinstrucţiunilor, adică prin folosirea unor
parametri. Nu toate funcţiile acestui nivel sunt rezidente în memorie, ci numai acele funcţii care
sunt cel mai des utilizate, iar celelalte se încarcă numai în funcţie de necesităţi.
Nivelul superior (3) constă din programe relativ rar apelate, care permit aducerea unui
program în starea în care să poată fi executat. Programele scrise în limbaje evoluate utilizează
S.O. tocmai la acest nivel.
Orice acces al programelor utilizator la funcţiile de la nivelele 2 şi 1 se realizează indirect
(şi din această cauză, acest nivel se numeşte suport de pregătire a programelor). Apelul la
componentele S.O. se realizează printr-un limbaj de comandă specific S.O. respectiv.
Într-o succesiune normală, un program de aplicaţie parcurge, înainte de a fi executat,
următoarele etape: introducerea în sistem, compilarea, editarea de legături, activarea programului.

4-3
Nu este obligatoriu ca toate lucrările să parcurgă toate aceste etape. Sunt lucrări la care fiecare
fază poate să apară o dată sau de mai multe ori.
Fiecăreia din etapele prezentate, în S.O. îi corespund programe specifice: compilatoare,
editoare de legături, editoare de rapoarte pentru prezentarea rezultatelor etc.

4.3. Caracteristici ale S.O.


Modul în care diversele S.O. implementează funcţiile specifice determină atributele S.O.
Punerea în evidenţă a acestor atribute este foarte importantă pentru că reprezintă un mijloc
obiectiv de comparare între diverse S.O.
Fiecare S.O. prezintă anumite caracteristici specifice, dar pot fi puse în evidenţă şi câteva
caracteristici de ordin general, valabile în orice sistem de operare, din care putem enumera:
1) Timpul de răspuns, calculat ca intervalul de timp între lansarea unei comenzi (cereri de
servicii către executiv) şi achitarea acesteia de către sistem. Acest atribut are în general două
componente distincte şi anume:
- timpul de aşteptare corespunzător intervalului de timp pentru ca cererea să fie luată în
considerare;
- timpul de execuţie (timpul necesar pentru a efectua operaţiile specifice cererii).
2) Simultaneitatea utilizării, se referă la gradul în care un sistem de calcul poate fi utilizat în
acelaşi timp de mai mulţi utilizatori (multiprogramare) sau să execute simultan mai multe
programe (lucrări) ale aceluiaşi utilizator (multitasking).
3) Eficienţa, reprezintă proprietatea S.O. de a folosi în mod optim resursele de care dispune
sistemul de calcul.
4) Partajarea şi protecţia, caracterizează gradul în care utilizatorii au posibilitatea să
utilizeze în comun informaţia prezentă în sistem, modul în care ei pot să comunice între ei fără ca
execuţia programelor specifice unui utilizator să afecteze execuţia programelor celorlalţi
utilizatori. Este necesar ca, interacţiunea dintre utilizatori să nu conducă la alterarea intenţionată
sau accidentală a informaţiei.
5) Generalitatea, flexibilitatea, extensibilitatea, măsoară gradul în care un S.O. poate fi
adaptat pe alte sisteme de calcul decât sistemul pentru care a fost creat. De asemenea, indică
gradul în care un S.O. poate fi dezvoltat, fie prin modificarea unora din funcţiile deja
implementate, fie prin introducerea de noi funcţii şi componente software şi hardware fără
eforturi deosebite de programare şi proiectare.
6) Fiabilitatea şi disponibilitatea unui S.O. este strâns legată de fiabilitatea întregului sistem
de calcul şi exprimă proprietatea sistemului de a funcţiona în continuu, fără a avea goluri de
funcţionare din cauza defectării sau blocării unor componente ale sale. Creşterea fiabilităţii se
poate face pe două căi:
- creşterea fiabilităţii componentelor hardware şi software precum şi introducerea rezervării
unor blocuri critice;
- utilizarea unor S.O. şi programe tolerante la defecte; aceasta înseamnă că, în cazul
apariţiei unor anomalii de funcţionare, S.O. asigură în continuare desfăşurarea activităţii
sistemului, acceptându-se o degradare a performanţelor în anumite limite impuse care nu
afectează însă esenţa activităţii sistemului.
Un accent deosebit se pune pe fiabilitatea şi disponibilitatea sistemelor în cazul utilizării
acestora pentru prelucrări în timp real.
7) Transparenţa şi vizibilitatea. Transparenţa indică gradul în care realizarea funcţiilor S.O.
se face fără aportul utilizatorului. Pentru utilizator, ceea ce se află sub interfaţa de utilizare care i
se oferă trebuie să fie invizibil, deci realizarea efectivă a funcţiilor S.O. trebuie să fie invizibilă.

4-4
Vizibilitatea indică măsura în care un utilizator poate avea acces la programele ce implementează
anumite funcţii ale S.O. Există situaţii în care, deşi nu este absolut necesar, utilizatorul are nevoie
să cunoască anumite informaţii specifice activităţii S.O. pentru a putea creşte eficienţa
programelor sale de aplicaţie.

4.4. Tipuri de sisteme de operare


Plecând de la caracteristicile S.O. şi având în vedere şi destinaţia sistemului de calcul
utilizat, s-a ajuns la următoarea clasificare a S.O.:
- S.O. secvenţiale;
- S.O. cu multiprogramare;
- S.O. în timp real;
- S.O. cu prelucrare multiplă.
Un sistem de operare secvenţial permite executarea, la un moment dat, a unui singur
program care trebuie terminat înainte de a se lua în considerare un alt program. Principalul
dezavantaj al acestui tip de S.O. este timpul de răspuns mare comparativ cu timpul de operare al
unităţii centrale.
Sistemele cu multiprogramare acceptă la un moment dat mai multe programe în memoria
centrală partajată, acestea aflându-se în diverse stadii de execuţie. Execuţia acestor programe se
realizează prin multiplexarea unităţii centrale, urmărindu-se obţinerea, la un grad de
simultaneitate cât mai ridicat, a unui timp de răspuns cât mai mic şi a unei eficienţe de utilizare
maximă. În acest caz utilizatorul nu poate să intervină la nivelul S.O. pentru a dirija modul de
execuţie a programului.
Un S.O. în timp real este dedicat unei anumite clase de aplicaţii. Prelucrarea în timp real
presupune o viteză de răspuns foarte mare pentru că toate cererile din proces trebuie luate în
considerare imediat ce au fost formulate.
Noţiunea de timp de răspuns este foarte elastică, domeniul de variaţie al acestuia fiind
foarte larg în funcţie de domeniul de utilizare al sistemului de calcul (microsecunde pentru
procese foarte rapide, până la ore în dirijarea unor procese economice).
În general, aplicaţiile implementate pe echipamente de calcul ce funcţionează în timp real
sunt în buclă infinită şi presupun o baleiere permanentă a datelor sosite din proces concomitent cu
calculul comenzilor corespunzătoare, iar intervenţia din partea operatorului este minimă.
Complexitatea S.O. în timp real este mult mai mare decât a celorlalte tipuri de S.O. pentru
că se impun performanţe deosebite pentru a satisface într-un timp critic diversele cereri sosite din
exterior.
Deoarece, în multe astfel de sisteme apare problema cooperării între diversele programe
executate, trebuie rezolvate probleme sofisticate privind sincronizarea şi comunicarea între
programe.
Un sistem de calcul dotat cu un S.O. cu prelucrare multiplă dispune de mai multe
procesoare care pot să execute simultan unul sau mai multe programe. În cazul execuţiei mai
multor programe independente, avem de-a face cu efectul de multiprogramare menţionat mai sus,
dar cu performanţe mult îmbunătăţite.
În cazul execuţiei simultane a unui singur program de către mai multe unităţi trebuie să
existe posibilitatea de descopunere a acestui program în părţi componente numite sarcini de
program sau taskuri, care în timpul execuţiei trebuie să coopereze între ele în vederea atingerii
obiectivului urmărit de program în ansamblu.
Un sistem de operare care oferă posibilitatea de a executa în paralel (sau simultan) mai
multe programe (taskuri) care interacţionează între ele, părţi componente ale unui program dat,
poartă denumirea de S.O. cu facilităţi multitasking.

4-5
Menţionăm însă că nici multiprogramarea şi nici multitaskingul nu impun capacitatea de
prelucrare multiplă din partea sistemului de calcul, deci astfel de S.O. pot fi implementate şi pe
sisteme monoprocesor.
Sistemele de calcul destinate conducerii proceselor industriale trebuie să posede în mod
necesar sisteme de operare în timp real cu facilităţi multitasking. O particularitate esenţială a unui
astfel de S.O. este aceea că el trebuie să fie accesibil utilizatorului care îi poate cere o serie de
servicii în vederea realizării evoluţiei dorite a programului.
Privit prin prisma utilizatorului şi a programelor de aplicaţii, ansamblul de programe al
acestui tip de S.O. poate fi împărţit în două categorii:
- programe necesare în faza de pregătire, elaborare şi testare a programelor de aplicaţii
(editorul de texte, compilatorul, link-editorul, debuggerul etc.) numite, din acest motiv, şi
programe de serviciu;
- programe necesare în etapa de conducere, care se leagă cu programele utilizatorului în
faza de dezvoltare, formând aplicaţia dedicată care se implementează pe echipamentul de
conducere.
Pentru a nu încărca în mod nejustificat atât din punct de vedere hardware cât şi software
echipamentul de calcul destinat conducerii procesului industrial, dezvoltarea aplicaţiei se va face
pe un alt sistem numit sistem de dezvoltare care va conţine ambele categorii de programe.

4.5. Principiile programării paralele


Consideraţii generale
Programarea paralelă sau concurentă este activitatea de scriere a unui program care conţine
o serie de părţi componente necesar a se afla în execuţie în acelaşi moment.
Orice aplicaţie în timp real conţine astfel de operaţii paralele care reprezintă etape de
execuţie asincronă a acesteia. Aşa cum am menţionat în capitolul anterior, părţile componente ale
programului ce pot fi executate în paralel poartă denumirea de taskuri. Din punct de vedere al
sistemului de calcul, taskul este cea mai mică unitate de prelucrare căreia i se atribuie o identitate.
Taskul reprezintă un program în formă executabilă compus dintr-o succesiune de
instrucţiuni executate secvenţial şi care realizează de obicei o anumită funcţie.
Dacă un task este încărcat şi executat în orice zonă a memoriei principale spunem că taskul
este relocabil. Fiecărui task i se asociază un indicator de importanţă numit prioritate. Alocarea
priorităţii poate fi fixă sau dinamică. În cazul priorităţilor fixe, înseamnă că, unui task i se alocă,
în faza de proiectare a aplicaţiei, o prioritate şi că aceasta nu poate fi modificată indiferent de
evoluţia ulterioară a procesului, pe când în cazul alocării dinamice a priorităţii, prioritatea unui
task se poate modifica pe baza anumitor criterii prestabilite în funcţie de evenimentele ce au loc
în proces. Alocarea dinamică a priorităţii este realizată de S.O., iar dezavantajul acestui procedeu
îl constituie complexitatea sporită a gestiunii lucrărilor (taskurilor).
Taskurile sunt activate în funcţie de priorităţile lor de o componentă a S.O. numită
PLANIFICATOR (SCHEDULER).
Rutinele (ROUTINES) sunt unităţi mai mici de program destinate tratării rapide a unor
evenimente. Sunt activate direct de S.O. la detectarea producerii unor evenimente în procesul
industrial. Detectarea acestor evenimente se realizează de regulă prin intermediul sistemului de
întreruperi al sistemului de calcul.
Subrutinele (SUBROUTINES) sunt cele mai mici unităţi de program apelate de taskuri.
Acestea pot fi: dedicate, adică specifice unui singur task sau comune, situaţie în care pot fi
apelate de mai multe taskuri sau rutine. Spre deosebire de taskuri care sunt întreruptibile,

4-6
subrutinele nu sunt întreruptibile, adică nu se acceptă întreruperea activităţii unei subrutine pentru
a trece la execuţia unui alt task. Acest lucru se datoreşte faptului că, în general, subrutinele
implică un timp de răspuns foarte mic, critic sau, altfel spus, sunt asociate unor evenimente
critice.
Există şi aşa numitele subrutine reentrante disponibile mai multor taskuri şi care pot fi
întrerupte deoarece nu sunt asociate unor evenimente critice.
Vom spune că două taskuri sunt paralele sau concurente dacă prima instrucţiune a unui task
demarează înainte ca ultima instrucţiune a celuilalt task să fi fost completată.
Dacă sistemul de calcul (conducere) este multiprocesor, paralelismul execuţiei taskurilor
poate fi asigurat în mod real în sensul că fiecare task poate fi executat de către un procesor. În
acest caz, se obţine o execuţie paralelă suprapusă în timp, numită şi execuţie paralelă fizică.
Dacă echipamentul de calcul este monoprocesor şi dotat cu un S.O. în timp real cu facilităţi
multitasking, execuţia paralelă a taskurilor se va face intercalat, pe principiul distribuirii timpului
unităţii centrale între taskuri ("time slicing"). La un moment dat, va deţine controlul procesorului
un singur task, dar datorită vitezei mari de lucru a acestuia, precum şi datorită modului de
programare se lasă impresia că taskurile se execută simultan, ca şi când fiecare task ar beneficia
de un procesor propriu - virtual, evident ceva mai lent. În acest caz, se spune ca are loc o execuţie
pseudo-paralelă sau o execuţie paralelă logică .
În cele ce urmează ne vom referi la acest din urmă mod de execuţie paralelă a taskurilor,
ceea ce corespunde situaţiei mai frecvent întâlnite în aplicaţiile de conducere şi supraveghere
automată a proceselor.
Pentru a putea realiza acest paralelism în prelucrarea taskurilor, arhitectura sistemelor de
calcul trebuie să conţină obligatoriu canale care să execute toate operaţiile de transfer de
informaţie, independent de procesor. Procesorul va avea doar rolul de a iniţia şi iniţializa operaţia
de I/E printr-un dialog adecvat cu canalul. În continuare canalul execută toate operaţiile de
transfer necesare, iar în încheiere semnalează procesorului, printr-un semnal de întrerupere, că şi-
a încheiat activitatea. Aceasta presupune existenţa unui sistem de întreruperi bine pus la punct.
Exemplu de execuţie a taskurilor în regim de multiprogramare
Considerăm cazul unui sistem în care există disponibile simultan trei taskuri T1, T2, T3.
Taskul T1 are prioritatea maximă, dar la iniţializarea sistemului, se presupune că este gata pentru
execuţie taskul T3.
Schematic, ocuparea de către cele trei taskuri a procesorului şi activitatea S.O. şi a canalelor
de I/E este reprezentată în următoarea diagramă.

4-7
Haşurat s-a reprezentat starea activă a unui task, a S.O. sau a CANAL-ului.
*** - reprezintă starea blocată a unui task, adică starea în care acesta nu poate fi executat,
fiind în aşteptarea unei resurse (pentru exemplul dat, resursa este un canal I/E).
------ reprezintă starea de întrerupere a unui task.
Iniţial, la pornirea sistemului, se execută programe specifice S.O. Acesta, va da la un
moment dat, controlul primului program gata de execuţie, adică taskului T3. La momentul (1),
taskul T3 iniţiază o operaţie de I/E. După ce transmite canalului toţi parametrii necesari executării
operaţiei de I/E, T3 trece în starea blocat pentru că aşteaptă rezultatele operaţiei de I/E iniţiate.
Aceasta conduce la preluarea controlului de către S.O., care va selecta acum taskul T1 (task care
are prioritate maximă în acest moment) căruia îi va da controlul.
La momentul (2) canalul lansează o întrerupere către procesor indicând încheierea operaţiei
de I/E iniţiată de taskul T3 ceea ce duce la suspendarea taskului T1 aflat în execuţie (trecerea lui
în starea întrerupt) controlul preluându-l S.O., care trece la o subrutină de tratare a întreruperii
sosite. După acceptarea şi tratarea întreruperii, taskul T3 trece din starea blocat în starea întrerupt.
Aceasta înseamnă că, din acest moment, execuţia taskului T3 poate fi reluată imediat ce se
încheie execuţia taskurilor de prioritate superioară.
După terminarea tratării întreruperii, la momentul (3) se reia execuţia taskului T1 pentru că
acesta este, în acest moment, de prioritate maximă. La momentul (4) şi taskul T1 lansează o
operaţie de I/E, după care trece în starea blocat, redând controlul S.O. Acesta va lansa în execuţie
la momentul (5) taskul cu prioritate maximă în acel moment, în cazul nostru taskul T2. După
terminarea operaţiei de I/E, canalul trimite, la momentul (6), un semnal de întrerupere, care
determină trecerea taskurilor T1 şi T2 în starea de întrerupere, controlul procesorului fiind preluat
de S.O. Acesta trece la subrutina de tratare a întreruperii generate de canal şi, după încheierea
tratării acesteia, dă controlul taskului T1 care are acum prioritate maximă. Terminarea execuţiei
taskului T1 determină reactivarea S.O. (momentul (7)), care va da controlul taskului T2, care la
terminarea execuţiei (momentul (8)) redă controlul S.O. Acesta reactivează taskul T3, iar după
terminarea acestuia (momentul (9)), controlul este preluat de S.O.
Din acest exemplu, se vede clar că în cazul programării paralele, un task este un ansamblu
indivizibil program-procesor.
În cadrul oricărui fel de execuţie paralelă există două categorii de taskuri peste un program
dat: taskuri disjuncte sau independente şi taskuri care interacţionează (sau care cooperează).
Două sau mai multe taskuri se numesc disjuncte dacă nu schimbă informaţii între ele sau
dacă nu utilizează resurse (zone de memorie, periferice etc.), în comun. În caz contrar, se spune
că ele interacţionează. Evoluţia unui program alcătuit numai din taskuri disjuncte este unică
indiferent de ordinea de execuţie a taskurilor. Dar, în cazul unei execuţii pseudo-paralele a două
sau mai multe taskuri peste un program dat, avem de-a face, în general, cu taskuri care
interacţionează.
Pentru o mai bună înţelegere a celor spuse prezentăm o serie de exemple.
Exemplul l: Fie o aplicaţie formată din trei taskuri: T1, T2, T3 având următoarea
componenţă:
Task T1 Task T2 Task T3
M1 = MAX(A, B) M2 = MAX(C, D) M = MAX(M1, M2)
Structura taskurilor este foarte simplă: T1 şi T2 calculează valoarea maximă dintre două
numere A, B, respectiv C, D, rezultatele fiind numerele M1, respectiv M2. Taskul T3 determină
maximul dintre M1 şi M2. Se observă imediat că taskurile T1 şi T2 sunt disjuncte, ordinea
execuţiei lor nealterând evoluţia în ansamblu a programului. Taskul T3, în schimb, cooperează cu
taskurile T1 şi T2 (preia valorile M1 şi M2 de la acestea) şi, ca atare, el trebuie să intre în
execuţie numai după terminarea execuţiei acestor două taskuri.

4-8
Ca urmare, ordinea de execuţie a taskurilor pentru o evoluţie corectă a programului dat va
fi: T1, T2, T3 sau T2, T1, T3, oricare altă ordine de execuţie având ca rezultat scăparea de sub
control a evoluţiei programului.
Exemplul 2: Fie o aplicaţie formată din două taskuri T1 şi T2.
Taskul T1 observă şi contorizează o serie de evenimente incrementând o variabilă
CONTOR. Taskul T2 tipăreşte ocazional numărul evenimentelor contorizate de taskul T1 şi după
fiecare tipărire anulează variabila CONTOR:
Task T1 Task T2
Observă evenimentul Tipareşte CONTOR
CONTOR = CONTOR + 1 CONTOR = 0
Se observă că cele 2 taskuri interacţionează între ele utilizând în comun variabila CONTOR
care se modifică în timp.
Dacă nu se iau măsuri speciale de programare, poate apare următoarea situaţie eronată:
presupunem că T1 a incrementat variabila CONTOR la 20, iar taskul T2 a tipărit aceaste cifre. Se
poate întâmpla însă ca înainte ca T2 să anuleze variabila CONTOR, taskul T1 să sesizeze un nou
eveniment şi să incrementeze variabila CONTOR de la 20 la 21. Rezultă deci că acest eveniment
se va pierde, el rămânând neraportat.
O altă situaţie, mai puţin evidentă, dar care conduce la rezultate eronate este următoarea:
Implementrea operaţiei CONTOR = CONTOR + 1 presupune existenţa mai multor
instrucţiuni în cod maşină:
- încarcă CONTOR în acumulator;
- incrementează acumulatorul;
- memorează conţinutul acumulatorului în CONTOR.
În timp ce taskul T1 execută această secvenţă, el poate fi întrerupt de T2 şi să se ajungă la
următoarea situaţie:
Presupunem că variabila CONTOR = 15 şi această valoare este încărcată în acumulator.
Considerăm că T2 tipăreşte valoarea 15 şi face CONTOR = 0. În continuare, taskul T1 adună 1 la
conţinutul acumulatorului şi memorează rezultatul 16 în CONTOR. Rezultă deci că au fost
raportate 15 evenimente, iar variabila CONTOR = 16 şi nu 0 cum ar fi trebuit să fie în mod
normal.
Exemplul 3: Se consideră 2 taskuri T1 şi T2 care scriu fiecare câte un mesaj pe consola
operatorului (display), folosind poziţionarea directă a cursorului în câte o poziţie (linie, coloană)
a consolei.
Task T1 Task T2
Poziţionează cursor în (L1,C1) Poziţionează cursor în (L2,C2)
Scrie MESAJ 1 Scrie MESAJ 2
MESAJ 1 şi MESAJ 2 sunt de fapt şiruri de caractere, iar (L1, C1) şi (L2, C2) numere de
linie şi coloană pe display (uzual, un display alfanumeric are 24 de linii şi 80 de coloane).
Dacă nu se iau măsuri speciale de protecţie, se poate ajunge la următoarea situaţie eronată:
taskul T1 preia controlul, poziţionează cursorul în linia şi coloana (L1, C1) şi începe să tipărească
MESAJ 1; dacă T1 este întrerupt înainte ca să fie terminată tipărirea lui MESAJ 1 şi controlul
este preluat de T2, acesta va poziţiona cursorul pe display în linia/coloana (L2, C2), va scrie
MESAJ 2, după care controlul revine lui T1, care continuă din punctul în care a fost întrerupt,
deci continuă tipărirea lui MESAJ 1; cursorul a rămas însă în poziţia lăsată de acţiunea taskului
T2 şi tipărirea lui MESAJ 1 este astfel compromisă.
Din aceste exemple rezultă clar că dacă nu se iau măsuri speciale de programare, în cazul
taskurilor care interacţionează, rezultatul nu poate fi prevăzut, aceasta datorită imposibilităţii
aprecierii momentului când se face transferul controlului.

4-9
Evoluţia unui program compus din astfel de taskuri nu este unică, ea depinzând de modul
de planificare al taskurilor spre execuţie, precum şi de timpul de execuţie al acestora. Pentru
obţinerea unei evoluţii dorite a programului, este necesară o programare foarte atentă care să
permită realizarea interacţiunii corecte între taskurile componente.

4.6. Gestiunea memoriei


Alături de procesor, memoria constituie o resursă fizică fundamentală a oricărui calculator
numeric.
Distingem: memoria principală sau operativă - MO reprezentând memoria internă a
sistemumlui de calcul şi memoria secundară sau externă. Se ştie că nici un program nu poate fi
executat dacă el nu se află depus în memoria operativă. Ţinând cont de lungimea, în general,
mare a programelor de aplicaţie în timp real, de obicei, acestea nu sunt integral rezidente în
memoria internă. Din această cauză, se impune ca, parţial sau total, programul să fie înmagazinat
pe un suport extern de memorie, de regulă, disc magnetic. După cum s-a arătat, fiecare program
de aplicaţie poate fi privit ca o reuniune de taskuri care interacţionează între ele.
Pentru a putea fi executat, la un moment dat, un task trebuie să fie complet încărcat în
memoria internă. Taskul trebuie să aibă alocată suficientă memorie, atât pentru el, cât şi pentru
datele pe care le vehiculează.
Rezultă că sistemul de operare trebuie să dispună de un mecanism special care să aloce
memorie internă diferitelor taskuri care sunt activate la un moment dat. Deoarece mai multe
taskuri pot îndeplini condiţiile de activare, la un moment dat, acestea cer să li se aloce spaţiu în
memoria internă. Având în vedere că memoria are o capacitate limitată, gestiunea memoriei
presupune introducerea unor tehnici de plasare şi înlocuire în memoria operativă a programelor şi
datelor aflate pe suporturi de memorie secundară. Alocatorul de memorie trebuie să rezolve
problema schimbului de informaţie între memoria operativă şi memoria secundară în mod
automat, printr-o tehnică de dute-vino (swapping) şi să determine în orice moment cum trebuie
distribuită informaţia în memorie, în scopul optimizării utilizării ei. Componentele sistemului de
operare prevăzute pentru gestiunea memoriei fac parte din suportul de execuţie a programelor şi
sunt situate deasupra suportului de gestiune a unităţii centrale.
Prin spaţiu de adresare se înţelege totalitatea numerelor de adresă referite într-un program.
În timpul execuţiei programului, fiecărei variabile din program îi va fi asociată o anumită adresă
din memoria operativă.
Gestiunea memoriei include două operaţii esenţiale:
- adresarea memoriei;
- protecţia memoriei.
Adresarea memoriei constă din procedee prin care se realizează asocierea între un element
al spaţiului de memorie şi o adresă efectivă din memoria operativă (un element al spaţiului de
adresare).
Protecţia memoriei constă din acele procedee care garantează utilizarea corectă a memoriei
operative de către toate taskurile aflate în execuţie la un moment dat.

Gestiunea memoriei în sistemele cu monoprogramare


În astfel de sisteme, la un moment dat, în memoria internă este încărcat şi se execută un
singur task, celelalte taskuri aflându-se pe suportul de memorie externă (disc magnetic). În
principiu, memoria operativă este împărţită în trei zone distincte, Fig. 4.3.

4 - 10
Fig. 4.3.
În zona rezervată sistemului de operare (SO) sunt plasate modulele rezidente ale SO sau
anumite module folosite temporar. Restul memoriei operative este disponibilă programelor
utilizatorului.
Suportul software pentru gestiunea memoriei în aceste sisteme este foarte redus. De regulă
se verifică dacă programele utilizator planificate pentru execuţie nu depăşesc capacitatea
memoriei operative disponibile în sistem (capacitatea MO - capacitatea zonei destinate SO). Dacă
se constată depăşirea capacităţii disponibile, se va emite un semnal de eroare, iar lucrarea
respectivă se va abandona. Mecanismele de protecţie a memoriei constau din procedee relativ
simple prin care se permite citirea informaţiei din zona aferentă SO şi interzicerea operaţiei de a
înscrie informaţii în această zonă. Sistemele de operare de acest tip se numesc monitor sau
supervizor . Funcţiile unui asemenea SO sunt:
1. Asigurarea continuităţii încărcării sistemumui. Aceasta înseamnă că în momentul în care
se termină execuţia unui task, controlul este preluat de supervizor, care iniţiază execuţia taskului
celui mai prioritar în acel moment, care preia şi controlul. Dacă taskul aflat în execuţie este
întrerupt (de un task mai prioritar), SO va suspenda execuţia taskului curent şi acesta, împreună
cu informaţia aferentă contextului când a fost întrerupt, va fi imediat transferat pe un suport de
memorie externă, în memoria operativă încărcându-se noul task ce urmează a fi executat.
Reluarea execuţiei taskului întrerupt se va face, după reîncărcarea acestuia în memorie, din
punctul în care a fost întrerupt.
2. Iniţierea şi achitarea operaţiilor de intrare-ieşire solicitate de programele utilizator.
3. Punera la dispoziţie, pentru programele utilizator, a unor rutine standard frecvent
utilizate.
Singura cale de a obţine accesul în zona aferentă SO de către programele utilizator constă în
apelul unor rutine ale SO.
Pprincipalul avantaj al acestei metode constă în simplitatea SO şi a spaţiului de memorie
mic ocupat de acesta, precum şi în faptul că se dispune pentru execuţia taskului curent de întregul
spaţiu al memoriei disponibile.
Dezavantajul metodei îl constituie timpul de răspuns mare datorat comutărilor frecvente
între taskuri sau de la un program la altul, deoarece transferul între memoria internă şi memoria
externă cere mult timp.
O metodă de a elimina acest dezavantaj constă în desemnarea unor taskuri critice pentru
care se impune un timp de răspuns minim, care rămân permanent într-o zonă protejată a memoriei
interne. De asemenea, utilizatorul are la dispoziţie un mecanism prin care va putea executa
programe, uneori cu mult mai mari decât spaţiul de adrese fizice disponibile. Acest mecanism se
numeşte metoda înlănţuirii şi suprapunerii (overlay) şi constă în suprapunerea unor module de
program. În acest caz, un program aplicativ sau un task aflat în execuţie controlează el însuşi
încărcarea de pe suportul extern a unor module de program sau taskuri. Încărcarea se face la
momente de timp bine definite impuse de evenimente externe sau interne, noile taskuri aducându-
se în memoria internă în zona proprie a programului apelant, putând să-l acopere parţial sau total.
Rezultă că programul de aplicaţie preia atât funcţia de planificare a execuţiei taskurilor, cât
şi de gestiune a memoriei interne, substituindu-se SO. Deşi această metodă presupune o
complicare a programului de aplicaţie, totuşi este foarte utilă pentru aplicaţii de complexitate

4 - 11
mică şi medie şi la care timpii de răspuns au valori foarte critice, precum şi în cazul sistemelor cu
divizarea timpului.
Dezavantajul esenţial al monoprogramării este acela că existând la un moment dat un singur
program în memorie, nu poate fi utilizat paralelismul între efectuarea operaţiilor de intrare-ieşire
şi operaţiile de prelucrare propriu-zise, ceea ce conduce la un timp de lucru global mult mai mare
şi un factor redus de utilizare a resurselor.
Cu toate acestea, această tehnică este foarte utilizată, mai ales, în cazul unor calculatoare de
putere mică şi medie destinate prelucrării unor lucrări cu caracter tehnico-ştiinţific. Astfel de
lucrări ocupă un timp îndelungat procesorul cu efectuarea unor operaţii aritmetice şi logice
complexe ceea ce face să se resimtă mai puţin influenţa timpului necesar schimbului informaţiei
între MO şi memoria externă.

Gestiunea memoriei în sistemele cu multiprogramare


Multiprogramarea a fost introdusă pentru creşterea gradului de utilizare a procesorului prin
exploatarea paralelismumui între activitatea procesorului şi activitatea dispozitivelor de intrare-
ieşire.
Multiprogramarea presupune existenţa simultană în memoria internă a mai multor taskuri şi
execuţia lor paralelă prin mecanismul multitasking. Comutarea între taskuri se realizează sub
controlul SO în funcţie de priorităţile taskurilor şi de evenimentele ce au loc în proces. Existenţa
mai multor programe în memoria operativă presupune împărţirea acesteia în zone distincte
numite partiţii sau regiuni. Situaţia alocării memoriei la un moment dat, într-un sistem cu
multiprogramare, se poate reprezenta ca în Fig. 4.4.

Fig. 4.4.
Se observă că, şi în acest caz, o anumită zonă de memorie va fi alocată necesităţilor SO.
Fiecare partiţie va fi formată dintr-o zonă utilă în care se încarcă programele şi datele aferente
unui task şi o zonă neutilizată. În ceea ce priveşte protecţia memoriei, apar două aspecte:
1. Ca şi în cazul monoprogramării este necesar ca programele utilizator să nu afecteze în
nici un fel informaţiile din zona SO.
2. Se impune ca execuţia unui program (task) să nu afecteze în nici un fel celelalte
programe (taskuri) cu care coexistă în memorie.
Un mecanism uşor de implementat care să răspundă cerinţelor de mai sus îl reprezintă
mecanismul cheie de protecţie - cheie de acces. Conform acestui mecanism, fiecărei partiţii i se
asociază, utilizând mijloace hardware, o cheie de protecţie. Când procesorul este alocat unui
program (task), câmpul din tabela de stare a taskului ce conţine cheia de acces la memorie va fi
actualizat corespunzător partiţiei programului curent aflat în execuţie. În timpul execuţiei, la

4 - 12
fiecare acces la memorie se verifică egalitatea cheii de acces cu cea a cheii de protecţie, accesul
fiind permis numai în partiţiile unde se înregistrează egalitatea.
Mecanismul cheie de protecţie - cheie de acces poate fi extins uşor şi la canalele de intrare-
ieşire.
Dacă memoria operativă este divizată în partiţii înainte de execuţia oricărei lucrări, se spune
ca lucrăm cu partiţii statice (fixe). În acest caz dimensiunea partiţiei este fixată încă din etapa de
generare a SO.
Într-o asemenea organizare, un program (task) dintr-o partiţie este executat până în
momentul în care va iniţia o operaţie de intrare-ieşire. Evident că cel care iniţiază propriu-zis
operaţia de intrare-ieşire este SO.
După iniţierea operaţiei de intrare-ieşire, SO va trece controlul unui alt task rezident în altă
partiţie a memoriei şi care dispune de toate resursele necesare cu excepţia procesorului. La fel se
petrec lucrurile şi în cazul în care un task este întrerupt de un task mai prioritar sau ca urmare a
apariţiei unui eveniment în proces: SO va da controlul taskului mai prioritar sau se trece la rutina
de tratare a întreruperii solicitate. Dacă într-o fază a lucrării cantitatea de memorie solicitată
depăşeste cantitatea de memorie ce poate fi pusă la dispoziţie într-o partiţie, întreaga lucrare se
abandonează.
Modul de alocare a memoriei cu partiţii fixe este indicat în situaţia în care se cunosc
dimensiunile programelor (taskurilor) şi zonele de memorie ocupate de datele pe care acestea le
vehiculează. În acest caz partajarea memoriei se va face în funcţie de necesităţi, obţinând deci o
bună utilizare a memoriei.
Dacă partiţiile sunt create nu la generarea sistemului, ci chiar în timpul execuţiei lucrării,
înaintea începutului fiecărei faze a lucrării, se spune că sistemul de calcul lucrează cu partiţii
dinamice. În această situaţie SO poate ajusta dimensiunea partiţiilor în funcţie de necesităţile
curente. Uneori aceste modificări se realizează chiar în timpul execuţiei unor programe prin
extensia sau reducerea memoriei alocate acestor programe. SO poate modifica şi numărul
partiţiilor existente la un moment dat în memorie. Aceste apecte impun ca SO să deţină informaţii
detaliate despre organizarea memoriei sub forma a două tabele: una, pentru partiţiile alocate şi
alta, pentru partiţiile libere. Informaţiile ce se păstrează în aceaste tabele se referă la dimensiunile
partiţiilor, adresa primei locaţii a partiţiei, rectricţiile de acces la fiecare partiţie.
Cele mai cunoscute procedee de alocare dinamică a memoriei sunt: procedeul FIRST FIT
(procedeul primei partiţii) - eficient în cazul programelor de dimensiuni mari şi procedeul BEST
FIT (procedeul celei mai bune partiţii) - specific în cazul unor programe mici şi cu o mare
diversitate. Alte algoritme de alocare dinamică a memoriei sunt: algoritmul înjumătăţirii
(BUDDY SYSTEM), care impune ca fiecare partiţie liberă să aibe o dimensiune egală cu o putere
a lui 2, algoritmul numerelor lui Fibonacci, care presupune o divizare a memoriei proporţională
cu numerele din şirul lui Fibonacci etc.
Deoarece alocarea dinamică a memoriei duce la apariţia unor fragmente de memorie
neutilizate, în general de dimensiuni mici, ceea ce duce la amânarea introducerii în execuţie a
unor lucrări noi până la terminarea unei lucrări în curs de execuţie ce eliberează o partiţie
suficientă de memorie, este necesar ca, periodic, aceste regiuni libere să fie combinate într-o
regiune mai mare, operaţie numită compactare sau recompactare a memoriei. Operaţia este foarte
costisitoare deoarece presupune deplasarea programelor în memorie, cu modificarea tuturor
adreselor (mai puţin adresele porturilor dispozitivelor de intrare-ieşire) şi se realizează printr-un
mecanism comun software-hardware.
Principalul avantaj al alocării dinamice, în special în cazul folosirii programelor relocabile
(adică programe ce conţin adrese relative după faza de editare a legăturilor) îl constituie
eliminarea fragmentării memoriei, cea ce duce la o utilizare mult mai eficientă a MO şi la un grad
superior de multiprogramare.

4 - 13
Dezavantajul constă în folosirea unor componente hardware suplimentare, reducerea vitezei
de lucru datorită timpului necesar pentru calculul adreselor efective şi creşterea timpului efectiv
de lucru datorită timpului mare necesar compactării memoriei, în special dacă această operaţie se
realizează frecvent.
Menţionăm că metoda este mai puţin utilizată în cazul SO cu divizarea timpului.

Gestiune memoriei operative prin paginare


Dacă se renunţă la cerinţa ca o partiţie să fie contiguă şi se prevăd dispozitive hardware
necesare, se obţine o soluţie la fragmentarea memoriei şi anume gestiunea memoriei prin
paginare.
Conform acestei metode, spaţiul de adresare al fiecărui program se consideră divizat în
părţi egale numite pagini; de asemenea, MO se consideră divizată în zone de aceeaşi dimensiune
numite blocuri de memorie sau cadre-pagină. Fiecărui program (task) i se alocă un număr întreg
de astfel de blocuri.
Alegerea dimensiunii blocului este o problemă de optimizare. Dacă blocurile sunt prea
lungi, se simplifică activitatea de gestiune, dar poate apare fenomenul de utilizare neraţională a
memoriei. Dacă blocurile sunt prea mici, eventualul câştig de memorie este plătit prin
complexitatea tabelelor de pagină şi a programelor de gestiune a memoriei.

4.7. Gestiunea proceselor (taskurilor) şi a procesorului


Se ştie că procesorul sau, mai general, unitatea centrală reprezintă principala resursă a
oricărui calculator. Orice program (task) destinat prelucrării datelor apelează la serviciile
procesorului.
Analizăm cazul unui sistem de calcul monoprocesor. În această situaţie, în cazul
multiprogramării, la un moment dat, mai multe taskuri din componenţa unui program pot solicita
resursele unităţii centrale. Apar, deci, conflicte pentru utilizarea procesorului.
Din punct de vedere al organizării funcţionale interne a unui calculator numeric, unui task îi
corespunde un proces.
Fiecare proces are asociate o serie de resurse care îi condiţionează desfăşurarea şi este
reprezentat în sistemul de operare printr-o structură de date numită bloc de comandă a procesului
(taskului).
Un bloc de comandă a procesului (taskului) va reflecta starea procesului (taskului) şi va
conţine toate informaţiile necesare pentru a relua procesul (taskul) din punctul în care a fost
întrerupt. Cu mici diferenţe de la un sistem de operare la altul, un bloc de comandă a procesului
(taskului) va conţine:
- identificatorul procesului (taskului);
- starea procesului (taskului);
- copia registrelor generale la suspendarea procesului;
- informaţii despre resursele alocate procesului.
Observaţie: Modul în care este creat un proces (task) este specific fiecărui sistem de
operare.
Taskurile care compun o aplicaţie se pot afla în una din următoarele trei stări:
NEINSTALAT, INACTIV sau ACTIV, Fig. 4.5.

4 - 14
Fig. 4.5.
Un task ACTIV poate fi, la rîndul lui, în una din următoarele substări: BLOCAT
(BLOCKED), GATA DE EXECUŢIE (READY) sau ÎN EXECUŢIE (RUN).
Un task neinstalat este un task creat rezident pe un suport extern sau în memoria internă a
calculatorului, dar care nu a fost încă adus la cunoştinta sistemului de operare
(EXECUTIVULUI). Un task creat este făcut cunoscut sistemului de operare prin operaţia de
instalare, în urma căreia el este trecut automat în starea INACTIV.
Un task se află în starea INACTIV dacă este instalat, dar nu este planificat pentru execuţie.
Prin instalare se creează şi i se alocă taskului un vector de stare sau un bloc de control al
taskului care reprezintă materializarea taskului în sistem şi care conţine informaţiile specificate
mai sus.
Vectorii de stare ai taskurilor sunt grupaţi într-o tabelă a taskurilor care este folosită de
sistemul de operare cu ocazia instalării şi distrugerii (ştergerii) taskurilor, precum şi pentru
efectuarea schimbărilor survenite în starea taskurilor pe parcursul duratei lor de existenţă.
Taskului i se atribuie un nume sau un număr care permite sistemului de operare şi altor
taskuri să-l desemneze fără ambiguitate pe toată durata lui de existenţă.
Un task poate reveni în starea NEINSTALAT numai din starea INACTIV prin operaţia de
ştergere (sau distrugere) a lui, dezafectîndu-i-se vectorul de stare.
Un task pentru care se face o cerere de intrare în execuţie trece din starea INACTIV în
starea ACTIV şi anume în substarea READY, tranziţia 1, adică are îndeplinite toate condiţiile şi
poate astfel concura la ocuparea procesorului. Momentul trecerii unui task în substarea GATA
DE EXECUŢIE nu poate fi prevăzut cu exactitate de către programator, acest moment fiind
funcţie de complexitatea aplicaţiei şi de modul în care se face planificarea taskurilor pentru
intrarea lor în execuţie. Precizăm că planificarea taskurilor pentru execuţie este realizată de un
modul al sistemului de operare numit planificator (SCHEDULER).
Trecerea unui task în substarea ÎN EXECUŢIE (RUN) se face numai din substarea
READY, tranziţia 2. Există două tehnici de bază pentru realizarea planificării taskurilor spre
execuţie:
10. Procedeul round-robin, prin care taskurile aşezate într-o coadă de aşteptare sunt
executate succesiv, fie până la terminarea lor normală, fie un interval (cuantă) de timp Δt bine

4 - 15
determinat. Strategia de administrare a cozii este de tip FIFO (First In - First Out : Primul venit -
Primul ieşit). După ce un task a fost executat, acesta este trecut în coada de aşteptare şi este lansat
în execuţie taskul următor. Dacă taskul nu se termină în timpul alocării curente, el este trecut prin
coada de aşteptare de n ori, unde n este cel mai mic întreg care satisface relaţia t ≤ n × Δt unde Δt
este cuanta de timp alocată rulării curente a unui task, iar t este timpul de execuţie al taskului. De
obicei, parametrul Δt se alege astfel încât majoritatea interacţiunilor utilizator-sistem să se
termine într-o singură cuantă (de regulă de ordinul milisecundelor). Se observă că, acest algoritm
întrerupe un task în curs de execuţie indiferent dacă la epuizarea cuantei de timp acordate taskul
respectiv s-a terminat sau nu.
20. Procedeul după priorităţi, prin intermediul căruia fiecărui task îi este atribuit un
indicator de importanţă materalizat printr-un număr numit prioritate, iar dintre taskurile gata de
execuţie, la un moment dat, care concură la ocuparea procesorului, sistemul de operare va aduce
ÎN EXECUŢIE taskul cu prioritatea cea mai mare la acel moment.
Observaţii:
1. În cazul EXECUTIVELOR care permit ambele moduri de planificare a taskurilor pentru
execuţie, procedeul round-robin se aplică taskurilor de aceeaşi prioritate.
2. Există sisteme de operare evoluate care oferă posibilitatea de activare a taskurilor în
condiţii de criză de timp şi care dispun de proprietatea remarcabilă de creştere automată a
priorităţii unui task dacă acesta nu a fost executat într-un anumit interval de timp.
3. Este evident că pe un sistem de calcul monoprocesor, la un moment dat, un singur task se
află ÎN EXECUŢIE.
Trecerea unui task dintr-o stare în alta se poate realiza, de asemenea, în două moduri:
10. Prin intermediul întreruperilor determinate de evenimentele interne sau externe generate
prin intermediul sistemului de întreruperi, contextul comutării fiind determinat de nivelul
întreruperii şi de subrutina de tratare a acesteia. Evenimentele ce sunt luate în considerare de
sistem sunt:
- întreruperi de la procesul condus;
- întreruperi de la ceasul de timp real;
- întreruperi generate de dispozitivele de intrare-ieşire;
- întreruperi iniţiate de operator de la COP;
- terminarea sau suspendarea executării unui task activ.
20. Prin directive (cereri de servicii) către sistemul de operare (EXECUTIV) din taskul care
se află în execuţie, contextul comutării fiind determinat de tipul directivei şi de parametrii
acesteia.
Un sistem de operare în timp real trebuie să permită ambele procedee de comutare a
taskurilor, aceasta şi datorită faptului că directivele folosesc implicit sistemul de întreruperi al
microprocesorului.
Mai mult, un EXECUTIV de timp real este necesar să fie însoţit de un MONITOR care să
constituie interfaţa între operator şi programul ce reprezintă aplicaţia de conducere şi care să
conţină comenzi având acelaşi efect asupra taskurilor ca şi directivele. Astfel, prin intermediul
MONITORULUI, operatorul se poate informa asupra stării taskurilor, poate realiza, dacă este
necesar, modificarea stării acestora, acţiuni necesare, mai ales, în faza de dezvoltare şi depanare a
programului.
Celelalte tranziţii ale unui task dintr-o stare în alta au loc în următoarele condiţii:
- Tranziţia 3 din substarea RUN în starea INACTIV apare în mod logic (sau normal) la
terminarea taskului.
- Tranziţia 4 din substarea RUN în substarea READY se realizează în două situaţii:

4 - 16
a) taskul curent este întrerupt de un alt task, de un task critic, mai prioritar, apărut în
condiţii de context extern sau intern;
b) în cazul modului de prelucrare a taskurilor în regim de time sharing (cu divizarea
timpului), când cuanta de timp alocată execuţiei taskului curent s-a epuizat, deşi el dispune în
continuare de toate resursele necesare execuţiei sale.
- Trecerea din substarea RUN în substarea BLOCKED, tranziţia 5, se realizează în situaţia
în care taskul aflat în execuţie este întrerupt pentru îndeplinirea uneia dintre următoarele condiţii:
a) terminarea unei operaţii de intrare-ieşire solicitată de task;
b) apariţia unui eveniment extern;
c) trecerea unui anumit interval de timp.
- Un task trece din substarea BLOCKED în substarea READY, tranziţia 6, când cauzele
care au produs blocarea execuţiei taskului au fost înlăturate, adică sunt îndeplinite condiţiile:
a) s-a încheiat operaţia de intrare-ieşire iniţiată de task;
b) s-a eliberat o zonă de memorie internă suficientă pentru a permite execuţia taskului;
c) a avut loc evenimentul extern aşteptat;
d) a expirat intervalul de timp de aşteptare.
- Tranziţia 7 din substarea READY în substarea BLOCKED apare în situaţia când un task
ce era gata de execuţie este trecut în substarea BLOCAT de un task aflat în execuţie, sau nu mai
poate fi executat din considerente că nu mai dispune de suficientă memorie internă.
- De asemenea, un task în execuţie poate trece, prin terminare forţată, în starea INACTIV
atât taskuri aflate în substarea READY, tranziţia 8, cât şi taskuri aflate în substarea BLOCKED,
tranziţia 9.
Observaţie: Prin terminare forţată, unui task activ i se suspendă toate condiţiile de
aşteptare şi i se retrage orice posibilitate de alocare a unei resurse.
Trebuie făcută menţiunea că dacă un task pierde controlul procesorului rămânând în starea
ACTIV, reluarea execuţiei lui se va face din punctul în care a fost întrerupt. Pentru ca reluarea
execuţiei să se facă în contextul întreruperii taskului este necesar ca, în momentul întreruperii
unui task, sistemul de operare să asigure salvarea întregului context aferent taskului, adică
conţinutul registrelor generale ale unităţii centrale, conţinutul registrului indicatorilor de stare etc.
Dacă comutarea stării taskurilor se face sub controlul unui EXECUTIV de timp real prin
intermediul directivelor, în urma lansării unei directive, controlul procesorului este transferat de
la taskul aflat în execuţie (taskul care a lansat directiva) către EXECUTIV pentru ca acesta să
satisfacă imediat cererea conţinută în directivă. Din punct de vedere al returnării controlului de
către EXECUTIV către taskurile componente aplicaţiei distingem două categorii de directive:
- Directive pe care EXECUTIVUL le satisface returnând apoi controlul taskului care a dat
directiva (care a lansat cererea de servicii);
- Directive care cer o serie de servicii EXECUTIVULUI, după satisfacerea cărora acestea
nu mai returnează controlul taskurilor apelante ci, determină o nouă replanificare (rescheduling) a
taskurilor pentru execuţie. EXECUTIVUL va aduce în execuţie taskul gata de execuţie cu
prioritatea cea mai mare. În acest caz, se spune că directiva declară eveniment semnificativ .
Structura generală a unui task executat sub controlul unui EXECUTIV de timp real este
prezentată în Fig. 4.6.

4 - 17
Fig. 4.6.

4 - 18

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