Sunteți pe pagina 1din 82

1.

Noiuni i termeni din domeniul resurselor tehnice


Un calculator const dintr-un ansamblu de componente funcionale fizice i logice, care coopereaz pentru
a satisface cerinele utilizatorilor privind introducerea, stocarea, prelucrarea, cutarea i transmiterea
informaiilor. Aceste componente funcionale sunt structurate pe niveluri, care interacioneaz prin interfee
bine definite. Prin noiunea de sistem de operare nelegem modulele program ale unui SC, care
administreaz resursele tehnice. Modulele n cauz soluioneaz situaiile de conflict, optimizeaz
productivitatea sistemului, sporesc eficiena utilizrii lui.
Valorile concrete ale atributelor sistemelor de operare i combinaii ale acestora determin diverse tipuri de
SO. Conform acestor atribute pot fi evideniate urmtoarele tipuri de sisteme de operare:

secveniale,

cu multiprogramare,

cu prelucrare multipl,

n timp real, etc.

2. Noiuni i termeni din domeniul SO


Un sistem de operare este un ansamblu de programe de control i de serviciu care ghideaz un calculator n
execuia sarcinilor sale, asist programele de aplicaie i interacioneaz cu utilizatorul prin intermediul
anumitor funciuni. Natura funciilor i modul n care acestea sunt realizate determin atributele care
caracterizeaz un sistem de operare: timpul de rspuns- exprim durata intervalului delimitat de lansarea
unei cereri de serviciu i achitarea acesteia de ctre sistem, simultaneitatea utilizrii- msoar gradul n care
un sistem poate s execute n acelai timp mai multe lucrri., eficiena- msoar proprietatea unui sistem de
a folosi n mod optim resursele de care dispune, partajarea resurselor i protecia informaiei n calculatorcaracterizeaz nivelul la care utilizatorii au posibilitatea s utilizeze n comun informaia prezent n sistem
i nivelul la care pot s comunice ntre ei, n deplin siguran, generalitatea, flexibilitatea, extensibilitatea,
fiabilitatea i disponibilitatea, transparena i vizibilitatea. Un sistem de operare este obligat:

s pstreze informaia despre starea fiecrei resurse,

s ia decizia crui proces s i se aloce resursa, n ce cantitate, cnd, cum i unde,

s aloce resursa i, la momentul oportun, s o retrag.

3. Tipuri de sisteme de operare, obiective i funcii


Valorile concrete ale atributelor sistemelor de operare i combinaii ale acestora determin diverse tipuri de
SO. Conform acestor atribute pot fi evideniate urmtoarele tipuri de sisteme de operare:
Un sistem secvenial (tratare pe loturi, engl. batch processing, fr. traitement par lots) execut la un moment
dat un singur program, care trebuie terminat nainte de a lua ncepe execuia unui alt program.
Sistemele cu multiprogramare accept la un moment dat mai multe programe n memoria central, acestea
aflndu-se n diferite stadii de execuie.
Un sistem de calcul cu prelucrare multipl dispune de mai multe procesoare, care pot s execute simultan
unul sau mai multe programe.

Sistemele de timp real funcioneaz, de obicei, n cadrul unor sisteme de comand i este necesar ca
valorile anumitor atribute s se ncadreze n limite destul de restrictive, dictate de dinamica proceselor
comandate.

4. Exemple de sisteme de operare


Windows,Unix, MS DOS.
5. Cazul calculatoarelor personale
Cea mai simpl configuraie a unui calculator personal (PC) include o unitate central, o memorie
principal, un display, o tastatur i un mouse. Aceast configuraie, de regul, este completat de o
memorie secundar i o imprimant.
Utilizatorul unui astfel de sistem va cere minimum urmtoarele dou tipuri de servicii:
identificarea i crearea unor fiiere sau mulimi structurate de informaii;
stocarea acestor fiiere n memoria secundar; transferarea informaiilor ntre fiiere i dispozitivele de
intrare/ieire;
execuia unor programe existente sau introduse sub form de fiiere n PC;
introducerea datelor necesare pentru execuia programului (de la tastatur, dintr-un fiier sau de la alte
surse periferice); listarea rezultatelor la display, imprimant sau copierea lor ntr-un fiier.
6. Comanda unor procese industriale
Procesul de producere este comandat de un calculator care ndeplinete urmtoarele funcii:

Reglare. Pentru o derulare bun a procesului de fabricaie parametrii de funcionare (temperatura,


presiunea, concentraia, etc.) trebuie s se afle ntr-o plaj de valori predefinite. Pentru aceasta va fi
acionat debitul de intrare a materiilor prime A sau B. Parametrii de funcionare sunt msurai cu
ajutorul unor captoare. Calculatorul preia aceste msurri i, n dependen de algoritmul de
comand, acioneaz robinetele de intrare.

nregistrare. Rezultatele msurrilor sunt periodic nregistrate; valorile lor sunt afiate pe un tablou
de bord i recopiate ntr-un fiier ("jurnal de bord") n scopul unor prelucrri ulterioare (date
statistice).

Securitate. n cazul n care unul dintre parametrii msurai depete o valoare critic predefinit
reactorul trebuie oprit imediat.

7. Sisteme tranzacionale
Caracteristicile principale:

sistemul gestioneaz un set de informaii sau baze de date, care pot atinge volume importante de
informaie;

asupra acestor informaii pot fi executate un anumit numr de operaii predefinite sau tranzacii,
adesea interactive;

sistemul este dotat cu un mare numr de puncte de acces i un mare numr de tranzacii se pot
derula simultan. Caracteristicile obligatorii ale unui astfel de sistem tranzacional sunt
disponibilitatea i fiabilitatea; pentru unele sisteme poate fi important i tolerana la defeciuni. O
caracteristic important ale sistemelor tranzacionale este multitudinea activitilor paralele, iar n
multe cazuri i repartizarea geografic a componentelor.

8. Sisteme n timp partajat


Destinaia principal a unor astfel de sisteme este furnizarea serviciilor necesare unei mulimi de utilizatori,
fiecare dintre ei beneficiind de servicii:

echivalente serviciilor unui calculator individual;

legate de existena unei comuniti de utilizatori: partajarea informaiilor, comunicaii ntre


utilizatori.

Problemele care apar datorit conceptului de partajare a timpului sunt o combinaie a problemelor existente
n cazul unui calculator individual cu cele din sistemele tranzacionale. Caracteristicile obligatorii ale unui
astfel de sistem mbin, n egal msur, calitile unui sistem de operare al unui calculator individual i al
unui sistem tranzacional, cum ar fi: disponibilitatea, fiabilitatea, securitatea, exploatarea optim a
caracteristicilor resurselor fizice, calitatea interfeei i serviciilor utilizatorului, facilitatea adaptrii i
extensibilitii.
9. SO i procesele
Noiunea de proces este asociat conceptului de lucrare i poate fi definit ca o suit temporal de execuii
de instruciuni, considerat ca fiind o entitate de baz n descrierea sau analiza funcionrii unui sistem.
Evoluia n timp a unui proces presupune un consum de resurse, dictat de natura i complexitatea
instruciunilor de execuie. n particular, rezult c ori de cte ori se execut procedurile de sistem,
resursele, pe care le utilizeaz acesta, intr n administrarea procesului, care a cerut serviciul. Resursele
alocate unui proces variaz n timp.
10. Maina extins i maiina ierarhic
Setul de instruciuni realizat hardware mpreun cu instruciunile suplimentare ale sistemului de operare
formeaz sistemul de comenzi al mainii extinse.
Nucleul sistemului de operare va fi executat pe maina goal, iar programele utilizatorului pe maina
extins.

11. Alte puncte de vedere asupra SO: abordarea funcional, interfaa cu utilizatorul
Sistemele de operare pot fi abordate din diferite puncte de vedere, cum ar fi SO i procesele, SO i maina
extins sau SO i maina ierarhic. Exist i alte puncte de vedere asupra sistemelor de operare pe care un
specialist ar trebui s le cunoasc.
Abordare funcional-Pentru un utilizator obinuit, convins c un calculator este doar un instrument care l
ajut n soluionarea unor probleme din domeniul su de activitate, noiunile, cum ar fi administrarea
memoriei cu paginaie sau driverele dispozitivelor, nu semnific prea multe. Destinaia principal a unui
sistem de operare pentru aceast categorie de utilizatori este punerea la dispoziie a unui set de programe
care l-ar ajuta n formularea i soluionare problemelor concrete ce in de domeniul su de activitate.
Abordare din punctul de vedere al interfeei cu utilizatorul
Interfaa sistemului de operare cu utilizatorul prezint un interes aparte. Progresul n acest domeniu este
spectaculos, dac vom lua n consideraie c n primele sisteme de operare utilizatorul era obligat s indice
n mod explicit i manual (n regim textual) fiecare pas, orict de nesemnificativ ar fi prut. Formularea
pailor cu ajutorul unui limbaj specializat, cum ar fi Job Control Language (JCL), nu a schimbat substanial
situaia.
12. Evoluia SO: de la "poart deschis " la tratarea pe loturi
Primele sisteme erau caracterizate prin prelucrarea secvenial a taskurilor. Timpul de execuie a
programelor era relativ mare, instrumentele de depanare primitive, fiecare programator i ncrca n mod
individual programul (pachetul de cartele perforate), apsa butoane, controla coninutul locaiunilor de
memorie, etc. (1950 1956). Au fost propuse programe de monitorizare (monitoare), care treceau de la o
lucrare la alta n mod automat, utilizatorul fiind responsabil de organizarea corect a programelor n cadrul
unui pachet primele ncercri de prelucrare pe loturi (1956 1959).
Dup 1965 au aprut primele sisteme cu partajare a timpului (time sharing), au fost propuse sisteme
sofisticate de administrare a informaiei Memoria virtual i mainile virtuale sunt nite principii care
nici pn astzi nu au fost exploatate pn la capt. Progresele ultimilor ani n domeniul resurselor tehnice
au permis implementarea acestor principii nu numai n cadrul sistemelor de calcul mari, ci i pentru
calculatoarele personale.

Primele calculatoare nu dispuneau de sisteme de operare. Fiecrui utilizator i se rezerva pentru un timp
determinat calculatorul cu toate resursele acestuia. Interaciunea era direct, programul i datele fiind
introduse n mod manual sub form de zerouri i uniti. Utilitele care au aprut aveau destinaia de a asista
elaborarea programelor (asambloare, compilatoare, etc.) sau de a facilitata operaiile de intrare-ieire.Acest
mod de exploatare, numit "poart deschis" , era de o eficacitate minim. Din aceast cauz la sfritul
anilor '50 au aprut primele "monitoare de nlnuire" - programe care permiteau executarea secvenial a
unui set de lucrri, pregtite anticipat, trecerea de la o lucrare la alta fiind automatizat.
13. Evoluia SO: multiprogramarea i partajarea timpului
Utilizarea principiului multiprogramrii sau partajarea memoriei ntre mai muli utilizatori a permis o
utilizare i mai bun a procesorului central. Exploatarea unui calculator conform principiului timpului
partajat ofer utilizatorilor posibiliti analogice unui calculator individual, permind beneficiul unor
servicii comune la un pre redus.
14. Organizarea intrrilor - ieirilor n memorii tampon
Pentru excluderea influenei perifericelor asupra vitezei de lucru a sistemului de calcul s-a propus s se
pstreze n memorie n anumite zone tampon datele de intrare i rezultatele mai multor lucrri.Dei
utilizarea memoriilor tampon prezint o serie de avantaje, totui dou momente negative pot fi menionate:

atunci cnd lucrarea n curs de execuie are nevoie de nite date unitatea central rmne inactiv pe
toat perioada citirii acestora;

o lucrare de scurt durat, sosit n timpul execuiei unei lucrri "lungi", trebuie s atepte
terminarea acesteia din urm.

15. Multiprogramarea
Multiprogramarea este un termen utilizat n cazul unui sistem n care pot exista simultan cteva procese
n stare de execuie. Un proces se consider n stare de execuie, dac calculele au nceput, dar la momentul
considerat nu au fost terminate sau ntrerupte. Multiprogramarea permite meninerea unitii centrale
n stare activ pentru perioada ncrcrii programelor sau operaiilor de intrare-ieire. Acest mod de
funcionare este adaptat tratrii pe loturi pe un calculator, care nu dispune de un mecanism de
reamplasare dinamic.
16. Sisteme cu timp partajat
Destinaia principal a unor astfel de sisteme este furnizarea serviciilor necesare unei mulimi de utilizatori,
fiecare dintre ei beneficiind de servicii:

echivalente serviciilor unui calculator individual;

legate de existena unei comuniti de utilizatori: partajarea informaiilor, comunicaii ntre


utilizatori.

Problemele care apar datorit conceptului de partajare a timpului sunt o combinaie a problemelor existente
n cazul unui calculator individual cu cele din sistemele tranzacionale i pot fi clasificate dup cum
urmeaz:

definirea mainii virtuale oferite fiecrui utilizator;

partajarea i alocarea resurselor fizice comune: procesoare, memorii, dispozitive de comunicaie;

gestionarea informaiilor partajate i a comunicaiilor.

17. Windows, Unix i alte sisteme


Paralel cu evoluia tehnic i funcional a sistemelor de operare a avut loc i o important evoluie
conceptual, care a permis o mai bun nelegere a funcionrii sistemelor de operare i a condus la
elaborarea unor metode proprii de concepere.
Debutul unei cercetri tiinifice a sistemelor de operare poate fi considerat anul 1964, care a succedat o
etap important de dezvoltare tehnic: primele sisteme cu partajare a timpului (Thor, CTSS). Sistemul de
operare UNIX, primul sistem mobil care asigur un mediu fiabil de dezvoltare i utilizare a softului de
aplicaie, este fundamentul practic de elaborare a sistemelor fizico-logice deschise.
18. S UNIX i standardele sistemelor deschise
Sistemul de operare UNIX, primul sistem mobil care asigur un mediu fiabil de dezvoltare i utilizare a
softului de aplicaie.
Implementarea larg a sistemului de operare UNIX a permis trecerea de la declararea sistemelor deschise la
dezvoltarea practic a acestui concept.
Variantele SO UNIX, propuse de compania SCO i destinate exclusiv platformelor Intel, sunt bazate pe
modulele iniiale ale System V 3.2, fiind total compatibile cu toate standardele de baz
Unul dintre primele standarde de-facto a fost cel publicat de USL pentru versiunea SO UNIX System V
Release 4 - System V Interface Definition (SVID).
Mai menionm standardul de-facto SPARC Complience Definition, propus de organizaia SPARC
International,
Pentru lumea UNIX este foarte important i standardul limbajului de programare C, adoptat mai nti de
ANSI i apoi de ISO. n acest standard sunt specificate, n afara limbajului C, bibliotecile necesare ntr-o
realizare standard. Deoarece chiar de la apariie limbajul C i sistemele de programare respective erau
strns legate de UNIX, componentele bibliotecilor standard corespundeau exact mediului standard al SO
UNIX.
19. OSF-1 i alte variante UNIX
Open Software Foundation (OSF) a fost prima companie comercial, care a ncercat elaborarea SO UNIX
n baza micronucleului Mach. A fost creat sistemul de operare OSF-1, care nu era n sens de liceniere
curat, deoarece folosea o parte a modulelor iniiale din SVR 4.0.
Nu putem s nu amintim aici i de realizarea original a SO UNIX pentru platformele Intel, propus de
Torvald Linus LINUX
Prin standard al unei interfee al SO subnelegem un set de proprieti, mai mult sau mai puin formale,
sintactice sau semantice ale componentelor sistemului de operare.
20. Standarde UNIX
Unul dintre primele standarde de-facto a fost cel publicat de USL pentru versiunea SO UNIX System V
Release 4 - System V Interface Definition (SVID).

Mai menionm standardul de-facto SPARC Complience Definition, propus de organizaia SPARC
International,
Pentru lumea UNIX este foarte important i standardul limbajului de programare C, adoptat mai nti de
ANSI i apoi de ISO. n acest standard sunt specificate, n afara limbajului C, bibliotecile necesare ntr-o
realizare standard. Deoarece chiar de la apariie limbajul C i sistemele de programare respective erau
strns legate de UNIX, componentele bibliotecilor standard corespundeau exact mediului standard al SO
UNIX.
21. Sisteme de operare cu micronucleu
Micronucleul este partea minim principal a unui sistem de operare, folosit pentru asigurarea
modularitii i transportabilitii.
Noiunea de micronucleu a fost introdus de compania Next prin sistemul de operare cu micronucleul
Mach.
Urmtorul SO cu micronucleu a fost MS Windows NT, n care momentul principal declarat era, n afara
modularitii, transportabilitatea. Acest sistem de operare poate fi utilizat n sistemele mono- i
miltiprocesor, bazate pe procesoarele Intel, Mips, i Alpha
Au aderat la tehnologia micronuclear i companiile Novell/USL, Open Software Foundation (OSF),
IBM, Apple i altele. Unul din concurenii principali ai lui NT n domeniul SO cu micronucleu sunt Mach
3.0, creat n Universitatea Carnegy-Mellon, i Chorus 3.0 al companiei Chorus Systems.
22. Modul secvenial de execuie a unui program. Noiuni fundamentale
Un program secvenial = o mulime de proceduri, care se pot apela reciproc. Fiecrei proceduri i este
asociat un segment distinct de procedur. Datele sunt reprezentate prin segmente, pot fi proprii unei
proceduri sau partajate ntre mai multe proceduri.
Numim activitate fenomenul care rezult din execuia nentrerupt a unei proceduri unice. !!Execuia unui
program secvenial const dintr-un lan de activiti!!!!
Numim context al unei activiti mulimea informaiilor accesibile procesorului n cursul acestei activiti.
Contextul activitii este compus din contextul procesorului (registrele programabile i interne) i contextul
memoriei (segmentul procedurii i segmentul datelor). Trecerea de la o activitate la alta este realizat de
instruciuni speciale: apelarea i returul din procedur, care realizeaz comutarea contextului.
23. Modul secvenial de execuie a unui program. Apelarea i returul
Operaiile executate la apelarea i returul procedurii sunt urmtoarele:
Apelare
1. alocarea unei zone n stiva de execuie pentru mediul procedurii apelate (dimensiunea acestei zone,
cu excepia spaiului de lucru, este cunoscut anticipat)
temp:=baza
baza:=top
top:=top+dimensiunea mediului
2. salvarea informaiilor de retur
baza_veche:=temp
memorizarea adresei de retur

3. ordonarea parametrilor
4. executarea unei ramificaii la procedura apelat.
Retur
1. salvarea rezultatului ntr-un amplasament stabilit
2. restabilirea informaiilor de retur i eliberarea mediului
temp:=adresa de retur
top:=baza
baza:=baza_veche
3. returul
ramificare *temp ramificare indirect
24. Activiti asincrone i protecia reciproc ntre activiti
Pentru cazuri mai generale sunt necesare mecanisme suplimentare, cum ar fi conceptele de asincronism sau
de protecie reciproc ntre activiti.
Prin asincronism nelegem efectul care l pot avea asupra derulrii unei activiti anumite evenimente
exterioare.
Numim protecie reciproc ntre activiti o modificare mai profund a contextului, atunci cnd se
trece de la o activitate la alta, n comparaie cu ceea ce are loc n cazul unei simple apelri de
procedur.
Un caz tipic de asincronism este executarea intrrilor-ieirilor simultan cu execuia unui program. Trebuie
s fie asigurat posibilitatea informrii programului despre terminarea unui transfer de informaii.
25. Mecanisme de comutare a contextului
Comutarea contextului unui procesor permite executarea ntr-o manier indivizibil (atomar) a
urmtoarelor dou operaii:
trecerea cuvntului de stare ntr-un amplasament specificat al memoriei,
ncrcarea n cuvntul de stare a coninutului unui alt amplasament specificat al memoriei. Comutarea
contextului poate fi necesar din mai multe cauze distincte. Presupunem c fiecrei cauze i-a fost asociat un
numr de ordine. Pot fi ntlnite dou scheme de comutare a contextului.
1. Salvare n amplasamente fixe.
2. Salvare ntr-o stiv.
26. ntreruperi
O ntrerupere este comutarea contextului procesorului declanat de o cauz extern derulrii instruciunii
curente. Fizic, ntreruperea nseamn trimiterea unui semnal procesorului, acest semnal provocnd
schimbarea strii unuia dintre indicatorii, consultai n cursul executrii fiecrei instruciuni. Semnalul
poate proveni de la alt procesor, de la un organ de I/E, de la un dispozitiv extern, i n genere, de la orice
proces fizic, extern procesorului ntrerupt. O ntrerupere permite s cerem procesorului s suspende
executarea programului curent, din primul punct ntreruptibil, i s treac la execuia unui program
predefinit. Acesta din urm este numit program de tratare a ntreruperii (interrupt handler, eng., traitant

de l'interruption, fr.). Programul de tratare a ntreruperii este executat ntr-un context diferit de cel al
programului ntrerupt, diferena fiind legat de modul de tratare, protecie, informaiile accesibile, etc.
27. Devieri i apelarea supervizorului
O deviere semnalizeaz o anomalie n derularea unei instruciuni, care prohibiteaz executarea
instruciunii. Originile pot fi diverse:
date incorecte, instruciune neexecutabil . Devierile pot fi clasificate, ca i ntreruperile, conform cauzelor
care le genereaz. O deviere poate fi suprimat, dar nici intr-un caz retardat. Un apel al
supervizorului (supervisor call, prescurtat SVC, eng., appel au superviseur, fr.) este o instruciune
chemat s provoace o comutare a contextului procesorului. Acest efect este analogic apelrii unei
proceduri, ns modificarea contextului este mai profund,
Destinaia unui apel al supervizorului este de a permite apelarea unei proceduri a sistemului de operare,
pretinznd la drepturi mai mari
28. Exemple de sisteme de ntreruperi
Sistemul de ntreruperi are 5 nivele (n ordinea de descretere a prioritilor): eroare hardware, deviere,
apelare supervizor, extern i intrare-ieire. Fiecrui nivel i corespunde n memoria operativ un cuplu de
amplasamente rezervate cuvintelor de stare vechi i nou. Fiecare nivel conine mai multe cauze de
ntrerupere.
29. Utilizarea devierilor i apelrii supervizorului
Simularea instruciunilor lips. Unele instruciuni din setul de baz de instruciuni ale procesorului pot fi
opionale i, deci, pot lipsi n unele configuraii ale calculatorului. Tentativa executrii unei instruciuni
opionale lips genereaz o drivere de tipul instruciune inexistent. Mecanismul devierilor poate fi utilizat
pentru a realiza prin program instruciunea inexistent n setul de baz. De exemplu, pentru o configuraie
n care operaiile aritmetice n virgul mobil nu sunt disponibile ele pot fi simulate prin apelarea
procedurilor corespunztoare. Aceste proceduri trebuie executate n mod slave pentru a permite tratarea
explicit a erorilor: ele sunt apelate prin ncrcarea cuvntului de stare respectiv. O adres de retur trebuie
s fie pregtit de ctre programul de tratare a devierii n top-ul stivei pentru a asigura returul la
instruciunea care urmeaz instruciunii de operaie aritmetic simulat.
Msurarea capacitii memoriei. Un sistem de operare presupune a fi utilizat pentru diverse configuraii
ale calculatorului. Capacitatea memoriei, numrul i natura dispozitivelor periferice, etc., pot fi diferite.
Sistemul de operare trebuie s se adapteze configuraiei concrete, ca i condiiilor particulare de utilizare
(numr de utilizatori, prioriti, etc.). Crearea unei asemenea versiuni specifice se numete generarea
sistemului de operare. Pentru a reduce frecvena generrilor S.O. unii parametri de configurare pot fi
determinai n mod automat la iniializare.
Gestionarea devierilor de ctre utilizatorul sistemului. Reacia standard la o deviere care are loc n
timpul execuiei unui program utilizator este apelarea unei proceduri de sistem, care provoac emiterea
unui mesaj de eroare, oprirea programului curent i trecerea la programul urmtor.
Este de dorit ca fiecare utilizator s aib posibilitatea s asocieze fiecrei cauze distincte de deviere i o
procedur proprie, tratarea creia ar nlocui reacia standard. Pentru a evita o bucl infinit, o deviere din
aceeai cauz i n interiorul acestei proceduri trebuie s apeleze procedura standard.
Asocierea unei proceduri proc de reluare a cauzei i de deviere se face cu ajutorul unui apel al
supervizorului (SVC asociere_deviere) cu parametrii i i proc.

Pentru trecerea la programul urmtor se va apela o procedur a sistemului de operare, apel realizat prin
ncrcarea unui cuvnt de stare, numit schimbare.
30. Exemple de utilizare a ntreruperilor
Principala utilizare a ntreruperilor este msurarea timpului i administrarea operaiilor de intrare-ieire.
Prezentm mai jos cteva exemple de utilizare a ceasului calculatorului.
procedura iniializare;
intr_ceas_nou:=<activ,master,mascat,adr intr_ceas>;
svc_nou :=<activ,master,mascat,adr tratare_svc >;
dezarmare(intr_ceas);
procedura tratare_svc;
save(zon);
case cod of

apel_lim_timp_ex:

-- parametrii p, q, tratare_eroare

ceas:=q;
cspretur:=svc_vechi;

-- salvare pentru retur

csplucrare:= <activ,slave,demascat,adr p>;


csperoare:= <activ,slave,demascat,adr tratare_eroare>;
armare(intr_ceas);
restabilete(zon);
ncarc_csp(csplucrare);

retur:

-- datorat terminrii procedurii p

dezarmare(intr_ceas);
ncarc_csp(cspretur);

endcase
procedura intr_ceas;

-- expirarea timpului limit

dezarmare(intr_ceas);
ncarc_csp(csperoare);
31. Programarea operaiilor de I/O. Organizarea general
Prin noiunea de intrare-ieire (prescurtat I/E; eng. input/output, I/O; fr. entre-sortie, E/S) numim orice
transfer de informaii din sau spre nucleul calculatorului. Operaiile de I/E semnific:
transferurile de informaii dintre diferite nivele ierarhice ale memoriei,

transferurile de informaii din sau spre mediul exterior (organe periferice locale sau la distan, captoare
sau dispozitive de acionare, alte calculatoare, etc.).
Organizarea general-Periferice, controlere, canale
Un organ de intrare-ieire este un dispozitiv capabil s transfere informaii ntre procesorul sau memoria
calculatorului i un suport extern de informaie. Acest transfer este comandat de ctre procesorul central. n
cel mai simplu caz, o instruciune special a procesorului permite transferarea informaiei ntre suportul
extern i un registru al procesorului, care va fi deci ocupat pe toat perioad transferului informaiei. Odat
cu evoluia calculatoarelor, n scopul unei mai bune utilizri a procesorului s-a ajuns la necesitatea acordrii
unei autonomii organelor de intrare-ieire ncredinndu-le funcii tot mai complicate de nlnuire i
comand, procesorului central lsndu-i-se doar iniiativa de lansare i de control a operaiilor. Din
considerente economice mai apoi s-a trecut la separarea dispozitivelor de comand a perifericelor de
perifericele propriu-zise, pentru ca dispozitivele de comand s poat fi partajate ntre mai multe periferice.
Cteva scheme de organizare a perifericelor sunt prezentate n fig.2.5. Schema (c) este proprie unui
calculator de putere mare, (a) i (b) corespund configuraiilor calculatoarelor de putere mai mic. Precizm
funciile organelor reprezentate n aceast figur.
1) Un canal (sau unitate de schimb) este un procesor specializat n operaiile de intrare-ieire. El poate fi
lansat doar de un procesor central, nu posed ntreruperi, dar poate ntrerupe un procesor central. Setul
de instruciuni ale canalului i permite s acioneze controlerele i perifericele, care-i sunt conectate.
Mini- i microcalculatoarele pot poseda organe, numite Uniti de acces direct la memorie (ADM), care
sunt nite canale simplificate.
2) Un contrler este un dispozitiv de comand adaptat la un tip concret de echipament periferic.
Autonomia sa este limitat de operaii foarte elementare. Destinaia principal a unui controler este de a
permite conectarea a mai multor periferice de acelai tip la un singur controler. Un singur dispozitiv
periferic poate transmite informaii prin intermediul controlerului la un moment de timp dat. n acelai
timp, este posibil executarea simultan a unor operaii pe alte periferice, operaii care nu implic
transferul de informaii (rebobinarea unei bande magnetice, deplasarea braului unui disc, etc.).
Partajarea funciilor ntre periferic i controler depinde de tipul perifericului. De obicei, funciile logice
(nlnuirea i sincronizarea operaiilor, emiterea unor semnale n caz de accident sau terminarea
normal a execuiei) sunt ncredinate controlerului, iar funciile fizice (transferul propriu-zis) perifericului. n programarea intrrilor-ieirilor nu este necesar, de obicei, s se fac o deosebire ntre
un controler i un periferic.
3) Un periferic este un organ capabil s transfere informaii din sau spre un suport extern. Controlerul este
legat de periferic printr-o interfa, care conine un set de funcii (intrare, ieire, semnalizri de
comand i de accident) i o linie de comunicaie, care servete la transferul informaiilor.

C
p
p p

UC: unitate
central
M: memorie
C: canal
ADM: acces
Fig. 2.5.
direct la
Organizarea
intrrilor-ieirilor memorie
Cp: controler
p: dispozitiv
periferic
C
p
p
(
c
)

U
C

(
a
)

C
p
p

U
C Magistral

Magistral

A
M
D
CM C
pp
pp
(
b
)
U
C
Magistral

C
C
M
p
p
p
p
U
C

Un canal poate comanda un singur dispozitiv periferic cu debit ridicat (disc, de ex.) sau poate fi multiplexat
pentru mai multe periferice cu debitul mai mic. ncercarea mai multor procesoare (uniti centrale sau
canale) de a accesa simultan memoria operativ poate genera conflicte. Conflictele sunt reglate de ctre
dispozitivul hardware de accesare, care impune o ordine de acces conform unor prioriti prestabilite.
Canalele au prioritate fa de unitile centrale, deoarece ele trebuie s reacioneze ct se poate de rapid la
evenimentele externe.
32. Metode de comand a perifericelor
Programul, care controleaz funcionarea elementar a unui dispozitiv periferic se numete driver.
Driverul gestioneaz n mod direct interfaa controlerului perifericului, trateaz ntreruperile generate de
acesta, detecteaz i trateaz cazurile de eroare. El este, de obicei, invizibil unui utilizator obinuit al
sistemului, care apeleaz funcii de intrare-ieire prin intermediul unor servicii de nalt nivel, realizate prin
apelri ale supervizorului.

33. Intrri-ieiri buferizate n memorie


Diferena considerabil dintre viteza de lucru a unitii centrale i cea a organelor periferice impune
"buferizarea" intrrilor-ieirilor, adic introducerea unei zone de memorie-tampon ntre periferic i
programul utilizatorului. Scopul este de a reduce timpul de inactivitate a unitii centrale, dezlegnd
funcionarea acesteia de periferice. Programul utilizatorului va transfera informaiile din sau spre zonatampon, iar aceast zon-tampon va servi, n mod paralel, drept surs sau destinaie la schimbul de date cu
perifericul. Dezlegarea unitii centrale de periferic este cu att mai bine realizat cu ct este mai mare
capacitatea zonei-tampon. Adesea, pentru a nu suprancrca memoria principal, zona-tampon este situat
pe discul fix.
34. ncrcarea iniial
Pentru a ncepe lucrul maina "goal" trebuie s aib ncrcat n memoria operativ programul sistemului
de operare i s execute un salt la prima instruciune a acestui program. Aceasta presupune prezena n
memorie a unui program de citire, care el nsui trebuie ncrcat n prealabil. La primele calculatoare, un
program de cteva instruciuni, introdus manual n memorie cu ajutorul unor comutatoare ale pupitrului de
comand la o adres fix, permitea ncrcarea unui program de citire mai elevat capabil s citeasc
versiunea complet a sistemului de operare. Acest proces era numit ncrcare (bootstrapping, eng.).
n calculatoarele contemporane, programul de iniializare se afl permanent ntr-o memorie constant
(BIOS). Execuia acestui program este declanat odat cu punerea sub tensiune a calculatorului
(autoncrcare).
35. Gestionarea activitilor paralele. Administrarea buferizat a intrrilor-ieirilor
Relum exemplul imprimrii cu gestionarea unor zone tampon pe disc, descris n capitolul 2. Analiza
acestui mod de funcionare (fig.3.1) pune n eviden patru activiti, care pot avea loc simultan:
1) primitiva scriere_linie

SL

2) scriere pe disc

SD

(canal 1)

3) citire de pe disc

CD

(canal 2)

4) imprimare fizic IF
scriere
_linie S
L

(unitatea central)

(canal 3)
S
D

C
D

tm1

I
F
tm2

(memo
rie)

td

(memo
rie)

(di
sc)
Fig.3.1. Gestionarea
buferizat a unei
imprimante

n realitate, citirea i scrierea pe disc sunt executate pe acelai canal, ceea ce poate impune unele restricii privind simultaneitatea executrii lor. Vom ignora aici
aceste restricii, justificnd mai apoi acest mod de procedare.

Aceste patru activiti sunt n mare msur autonome, or ele sunt executate pe procesoare distincte, cu
programe diferite. Ele nu sunt totui independente, deoarece acceseaz obiecte comune: dou tampoane n
memorie, tm1 i tm2 i un tampon pe disc, td. Pot fi evideniate dou tipuri de condiii, care trebuie
respectate:
1) Condiii, care stabilesc posibilitatea existenei unor activiti
O nregistrare nu poate fi preluat dintr-un tampon nainte de a nu fi depozitat aici. Tampoanele au
capaciti limitate; dac un tampon este ocupat cu nregistrri, care nu au fost nc preluate, este imposibil
depozitarea fr a pierde informaii. Aciunile de depozitare i preluare sunt, deci, supuse unor condiii de
posibilitate de existen, enumerate mai jos.
Activitate

Aciune

Condiie

SL

scriere n tm1

tm1 nu este plin

SD

citire din tm1

tm1 nu este vid

SD

scriere n td

td nu este plin

CD

citire din td

td nu este vid

CD

scriere n tm2

tm2 nu este plin

IF

citire din tm2

tm2 nu este vid

Execuia activitilor modific veridicitatea acestor condiii: astfel, imprimarea unei linii pune n TRUE
condiia tm2 nu este plin.
O activitate, care nu poate executa o aciune, deoarece condiia asociat are valoare FALSE, trebuie s
atepte, adic execuia unei aciuni este retardat pn cnd valoarea logic a condiiei devine TRUE. n
capitolul 2 a fost discutat realizarea acestui mecanism de ateptare i continuare cu ajutorul ntreruperilor.
2) Condiii de validitate a informaiilor partajate
Dac vom examina procesul de accesare a tampoanelor, vom descoperi o alt form de interaciune,
cauzat de posibilitatea de accesare simultan de ctre dou activiti a unui amplsament de memorie.
Astfel, dac SD citete coninutul unei nregistrri din tm1 pe care SL este n curs de a o modifica,
rezultatul acestei citiri risc s fie incoerent, dac nu au fost luate msuri speciale de precauie. Problema
poate fi rezolvat impunnd una din activiti, aflate n conflict, s atepte pn cnd cealalt va termina
accesarea.
Concluziile acestei prime analize:
Lucrarea imprimare tamponat este realizat prin patru activiti simultane, n mare msur autonome,
care coopereaz pentru atingerea scopului final.
Executarea corect a lucrrii impune restricii logice n vederea derulrii acestor activiti. Aceste restricii
pot conduce la ntrzierea execuiei unei activiti, care este obligat s atepte producerea unui eveniment,
provocat de o alt activitate.
36. Gestionarea activitilor paralele. Comanda unui proces industrial
Considerm dou reactoare identice, R1 i R2, care funcioneaz n paralel. Vom examina dou soluii
posibile:
1) utilizarea a dou calculatoare (cte unul pentru fiecare reactor),
2) folosirea unui singur calculator pentru comanda ambelor reactoare.

Prima variant nu prezint nimic nou n raport cu descrierea din capitolul 1. Soluia a doua cere stabilirea
condiiilor suplimentare pentru realizarea sa. Implementarea variantei doi impune verificarea posibilitii
apariiei unor condiii suplimentare. Fie P1, P2, D1, D2 segmentele procedurilor i datelor pentru comanda
celor dou reactoare R1 i R2, memoria principal avnd capacitatea necesar pentru pstrarea acestor
segmente. Programele P1 i P2 sunt executate pe rnd de procesor. Raionnd ca i n capitolul 1,
concluzionm c relaia 2t<T trebuie s fie respectat. Dac acesta va fi cazul, funcionarea reactoarelor
pentru un observator extern pare identic pentru ambele soluii. Trebuie, totui s subliniem, c soluia doi
impune restricii mai severe n ceea ce privete performanele calculatorului (capacitatea memoriei i viteza
de procesare)
Vom examina mai jos modalitile de implementare a soluiei doi.
Partajarea procesorului
ntre dou execuii succesive ale lui P1, procesorul este utilizat de P2, ca rezultat starea sa intern
(coninutul registrelor, cuvntul de stare, contorul ordinal) va fi modificat. Pentru a permite reluarea lui P1,
informaiile sale trebuiesc salvate la terminarea fiecrei secvene de execuie i restabilite la nceperea
execuiei urmtoare. Aceleai afirmaii sunt valabile i n cazul executrii lui P2.
Partajarea programului
Programele P1 i P2, fiind identice, putem pstra doar o singur copie, s-i zicem P, pentru economisirea
memoriei. S examinm condiiile necesare pentru partajarea programului P:
nu este permis modificarea codului programului de execuia sa,
atunci cnd P este executat pentru reactorul Ri (i=1 sau 2), el va accesa segmentul de date Di; aceast
adresare selectiv a datelor va fi realizat de un mecanism care nu modific textul programului.
Un program, existent n exemplar unic, dar care poate fi utilizat pentru executarea mai multor activiti
independente, eventual simultane, se numete program reentrant (reenterabil). Acest mod de utilizare
implic:
invariana textului programului n cursul executrii sale,
desemnarea uniform, de ctre program, a datelor proprii fiecrei activiti.
Printre altele, dac activitile partajeaz un procesor unic, informaiile despre starea acestuia (n particular,
cele care servesc la desemnarea datelor) trebuiesc salvate la fiecare comutare.
S rezumm rezultatele celui de-al doilea exemplu.
Au fost evideniate dou activiti logic independente: comanda reactoarelor R1 i R2. Aceste dou
activiti pot fi puse pe dou maini distincte fr s existe vre-o legtur ntre ele.
Considerente de economie pot impune ca aceste activiti s partajeze resurse fizice i resurse
program comune. Buna funcionare a acestei partajri restricioneaz execuia activitilor
(utilizarea alternativ a procesorului) i modul de utilizare a obiectelor partajate (salvarea
contextului de executare, reentrana programelor).
Ca i concluzie pentru ambele exemple putem evidenia dou momente:
existena unor activiti evolutive, care pot derula simultan,
existena unor relaii ntre aceste activiti: cooperare pentru executarea unor sarcini comune,
concuren n utilizarea resurselor partajate. Aceste relaii sunt determinate de specificaiile de bun
funcionare. Ele se pot traduce n restricii de execuie, care conduc la ntrzieri temporare a
progresrii unei activiti.

37. Noiune de proces secvenial. Proces unic. Context


Noiunea de proces este mai nti introdus ntr-un mod concret pentru cazul unui calculator care conine
un procesor unic i o memorie adresabil. Vom trece mai apoi la definiia abstract a unui proces
independent de suportul su fizic, ceea ce ne va permite introducerea problemei sincronizrii.
Noiunea de proces pune la dispoziie un model pentru reprezentarea unei activiti, care rezult din
executarea unui program pe calculator. Starea calculatorului este definit de starea procesorului (coninutul
registrelor) i starea memoriei (coninutul amplasamentelor). Aceast stare este modificat de ctre
procesor prin executarea instruciunilor programului. Fiecare executare a unei instruciuni constituie o
aciune: o aciune are ca efect trecerea n timp finit a calculatorului dintr-o stare iniial ntr-o stare final.
Acest efect este descris n specificaiile instruciunii.
Executarea unei instruciuni va fi considerat indivizibil sau atomar, adic este interzis observarea sau
definirea strii mainii n timpul acestei execuii. Timpul utilizat pentru descrierea evoluiei strii este un
parametru t, care poate lua o serie de valori discrete cresctoare, corespunztoare nceputului i sfritului
instruciunilor. Aceste instane sunt numite puncte de observare, iar strile corespunztoare ale mainii
sunt numite puncte observabile. Prin abuz de limbaj, acest ultim termen desemneaz n egal msur i
punctele de observare. Acestea permit s se asocieze o dat (valoarea curent a lui t) unei stri a mainii; o
atare stare datat definete un eveniment. Evenimentele permit reperarea modificrilor strii mainii.
nceputul i sfritul unei aciuni a sunt evenimente datele crora sunt notate nceput(a) i sfrit(a); vom
avea, evident, nceput(a)<sfrit(a).
Executarea unui program se traduce, deci, ntr-o suit de aciuni a1, a2,..., ai,..., cu nceput(ai)<sfrit(ai).
O astfel de suit este numit proces secvenial (sau simplu proces).
Un proces poate, deci, fi descris cu ajutorul succesiunii evenimentelor nceput(a1), sfrit(a1), nceput(a2),
sfrit(a2),... Aceast suit de stri datate ale mainii se numete traiectorie temporal (sau istorie) a
procesului. Putem de asemenea defini un proces ca o suit de activiti n sensul lui 2.1.
Mulimea informaiilor pe care aciunile unui proces le pot consulta sau modifica se numete contextul
procesului. Relund modelul de execuie secvenial introdus n 2.1, contextul unui proces rezultant din
executarea unui program conine:
1) Contextul procesorului (cuvntul de stare i registrele),
2) Un context n memorie, sau spaiul de lucru (segmente procedur, date, stiv de execuie),
3) O mulime de atribute ataate procesului i care specific diferite proprieti:
a) Nume. Numele unui proces, care servete pentru identificarea lui, este de regul, un numr intern
atribuit la crearea procesului i care permite s se ajung la reprezentarea contextului su (v.4.2).
b) Prioritate. Prioritatea proceselor permite ordonarea lor pentru alocarea procesorului (v.4.2, 4.3). Dac
toate procesele au aceeai prioritate, alocarea se face conform ordinii primul sosit, primul servit.
c) Drepturi. Drepturile unui proces specific operaiile care i sunt permise, n scopul asigurrii proteciei
informaiei (v. 5.1.4).
38. Relaii ntre procese. Mulimi de procese. Paralelism

ntr-un mod mai riguros ar trebui s adugm aici punctele ntreruptible care pot fi prezente n unele instruciuni de lung durat; o executare a unei
asemenea instruciuni poate fi considerat o suit de mai multe aciuni.

Pentru comoditatea expunerii considerm, c sfritul unei aciuni i nceputul aciunii urmtoare sunt dou evenimente distincte, datele crora sunt diferite,
dei strile corespunztoare sunt identice.

-traiectoria temporal a unei mulimi de procese este irul evenimentelor formate de nceputurile i
sfriturile aciunilor rezultante din executarea programelor acestor procese.
-contextele unor procese diferite pot avea pri comune. Dou procese, contextele crora sunt disjuncte, se
numesc independente; ele nu pot avea interaciuni reciproce. Partea contextului, care aparine unui singur
proces, se numete context privat al procesului dat.
S considerm dou programe distincte P i Q, fiecare avnd n memorie un segment cod i un segment de
date. Numim p i q procesele rezultante din executarea respectiv a acestor dou programe. Executarea
setului (p, q) poate s se produc n diferite moduri, caracterizate de forma particular a traiectoriei sale
temporale. Aceste traiectorii sunt reprezentate n figura 3.2.
Schemele de mai sus pot fi comentate astfel:
schema 1: este executat mai nti tot procesul p, apoi procesul q la fel n ntregime,
schema 2: sunt executate iruri de instruciuni ale procesului p n mod alternativ cu iruri de instruciuni
ale procesului q, i tot aa pn la terminarea ambelor procese,
schema 3: executarea proceselor p i q este simultan; n acest caz sunt necesare dou procesoare.
Pentru compararea acestor scheme de execuie introducem noiunea nivel de observare. Putem considera o
suit de aciuni ale unui proces ca o aciune unic, adic s observm derularea unui proces considernd o
unitate de execuie

mai puin fin dect instruciunea. De exemplu, dac vom redefini noiunea de aciune elementar ca
execuie a unei proceduri, traiectoria procesului va conine doar strile definite de fiecare apel i retur de
procedur. Nivelul de observare cel mai fin (cel al instruciunilor) este numit nivel de baz.
S ne situm mai nti la nivelul de observare la care, prin convenie, executarea complet a fiecrei dintre
programele P i Q reprezint o aciune unic. Definiiile care urmeaz sunt pentru acest nivel.
a) schema de tip 1 este a unei execuii secveniale a lui p i q. Ea este caracterizat de relaiile:
sfrit(q) < nceput(p) sau sfrit(p) < nceput(q)
b) schemele de tip 2 sau 3 sunt scheme de execuie paralel. Ele sunt caracterizate de
sfrit(p) > nceput(q) sau sfrit(q) > nceput(p).
Revenim la nivelul de baz. Putem face o distincie ntre schemele 2 i 3. ntr-adevr, n schema 2, din
considerente de existen a unui singur procesor, la un moment de timp dat doar o singur aciune poate fi
executat, contrar schemei 3. Se va spune c n schema 3 are loc un paralelism real, iar n schema 2 un
pseudo-paralelism. Paralelismul real necesit dou procesoare distincte. Dou observaii importante sunt
necesare:
1) Diferena acestor scheme de execuie este legat de alegerea nivelului de observare. Astfel, la nivelul de
baz, diferena dintre schemele 1 i 2 dispare: ambele sunt secveniale.

2) Alegerea nivelului de baz depinde de fineea fenomenelor, care dorim s le considerm elementare.
Dac trebuie s studiem executarea instruciunilor n pipe-line pe un procesor microprogramat, n
calitate de nivel de baz va fi ales
39. Concurena proceselor. Resurse virtuale
Situaia descris de schemele 1 i 2 nu rezult dintr-o legtur logic ntre p i q, ci doar din existena unui
singur procesor. Ea poate fi caracterizat astfel: fie o mulime de procese contextele crora au un obiect
comun, care poate fi utilizat la un moment de timp dat de un singur proces. Se va spune n acest caz, c
obiectul constituie o resurs critic pentru procesele date sau c procesele sunt n excludere mutual
(excludere reciproc sau concuren) pentru utilizarea unei resurse. n situaia descris, procesorul este o
resurs critic pentru procesele p i q.
Observm c excluderea mutual a unei resurse conduce la serializarea execuiei proceselor concurente,
n cazul unor aciuni, care cer aceast resurs (n exemplul dat, toate aciunile). Schemele 1 i 2 difer doar
prin nivelul de finee la care este executat serializarea.
Funcionarea corect a unei mulimi de procese, care particip la ndeplinirea unei lucrri comune, implic
relaii logice de cooperare (v.3.1.1). Este comod s se separe aceast cooperare de concurena pentru
resursele fizice cu scopul de a simplifica nelegerea i aplicarea celor dou tipuri de relaii. Pentru aceasta
este folosit noiunea de resurse virtuale: fiecrei resurse fizice critice i se asociaz tot attea copii
imaginare (sau virtuale) ale acestei resurse cte procese concurente solicit utilizarea ei. Suntem nevoii s
tratm dou probleme distincte:
1) respectarea relaiilor de cooperare ntre procesele, care, fiecare posed (conceptual) resursele fizice
solicitate i pentru care paralelismul n execuie nu este restricionat de competiia pentru resurse,
2) reglarea problemei de concuren pentru resursele fizice printr-o serializare convenabil a execuiei
proceselor n cauz. Se va spune n acest caz, c realizm o alocare a resurselor fizice.
Introducerea resurselor virtuale are o consecin foarte important pe care o vom ilustra-o prin exemplul
proceselor p i q, definite n 3.2.2.1. S atam fiecrui proces un procesor virtual. Conceptual, totul va
avea loc ca i cum procesele s-ar derula paralel, conform unei scheme, numite logice sau virtuale, analogice
schemei 3 din fig.3.2. Cu toate acestea, trebuie de menionat, c aceast schem logic reprezint doar o
notaie compact pentru mulimea schemelor reale posibile i c ele sunt obligatoriu de forma 1 sau 2 din
considerentele unicitii procesorului. Pentru o schem real i una virtual a unui proces dat este pstrat
doar ordinea de succesiune a evenimentelor (nceputul i sfritul aciunii) i nu sunt pstrate valorile
absolute ale intervalelor de timp, care le separ. n absena altor informaii, nu putem spune nimic apriori
despre ordinea evenimentelor, asociate unor procese distincte. Timpul folosit la reperarea evenimentelor n
schema logic este numit timp logic; relaiile sale cu timpul real sunt prezentate n fig.3.3.
a1

a2

+------+-----------------+------+
b1

b2

procesul p

(timp logic)

+--+-------+---------+ procesul q
a1

a2

+------+---+

+----------+ +----+------+ p

+--+--+
b1

b2

a1

a2

+-----+---------+

(timp real, execuia 1)

+---+

+---+-----------------+------+ p
+--+----+
b1

+---+---------+

(timp real, execuia 2)

b2

n toate cazurile a1 precede a2, b1 precede b2.


Fig.3.3. Timpul logic i timpul real
Vom considera, c evoluia proceselor are loc n timp logic, adic vor fi interzise orice ipoteze despre viteza
relativ a proceselor n cauz: aceasta este consecina simplificrii considerabile, introduse de noiunea de
resurse virtuale, care permite ignorarea mecanismelor de alocare. O singur excepie, totui va fi fcut
pentru studierea sincronizrii temporale, n care timpul fizic intervine n mod precis ca msur a duratei i
nu numai ca mod de reperare relativ.
40. Excluderea mutual.
Introducerea resurselor virtuale ne permite s tratm problema excluderii mutuale la accesarea resurselor
fizice corespunztoare n cadrul mecanismelor de alocare. Aceast problem poate fi pus ntr-un alt mod
cum o demonstreaz exemplul urmtor.
Exemplu 3.3. Dou procese p i q trebuie fiecare s actualizeze valoarea unei variabile comune n (de
exemplu, n este starea unui cont bancar pentru care p i q efectueaz o depozitare). Aciunile respective se
vor scrie n programele lui p i q:
procesul p:

Ap : n=n+np procesul q:

Aq : n=n+nq

S realizm decompoziia acestor aciuni n instrucii, notnd prin Rp i Rq registrele locale ale proceselor
p i q respectiv:
procesul p

procesul q

1. load Rp, n

1. load Rq, n

2. add Rp, np

2. add Rq, nq

3. sto Rp, n 3. sto Rq, n


Dac aceste aciuni sunt executate n ordinea 1, 1, 2, 2, 3, 3, efectul lor global este de executat n:=n+nq i
nu n:=n+np+nq: una din actualizri a fost pierdut i valoarea final a variabilei n este incorect. Pentru
evitarea acestei incoerene aciunile Ap i Aq trebuie s fie executate n excludere reciproc; se zice de
asemenea c ele constituie pentru p i q seciuni critice. Este necesar s se respecte condiia
sfrit(Ap) < nceput(Aq) sau sfrit(Aq) < nceput(Ap).
Aceast condiie de serializare, care are efectul de a face Ap i Aq s devin atomare, este identic condiiei
deja ntlnite n 3.2.2.2 la accesarea unei resurse fizice critice.
Excluderea mutual const n extinderea pentru secvena de aciuni a proprietii de indivizibilitate a
aciunilor nivelului de baz (aciuni atomare). Posibilitatea executrii unor aciuni atomare se afl la baza
mecanismelor care realizeaz sincronizarea.
41. Sincronizarea proceselor-42,43
42. Exprimarea i implementarea restriciilor de precedare
Introducem dou exemple, care ne vor ajuta la formularea restriciilor logice impuse de cooperare.

Exemplul 3.4.Procesul p transmite informaii procesului q scriind ntr-un segment a, consultat de q (se
presupune c aceast transmitere are loc o singur dat). Este necesar s se verifice condiia:
sfrit(scriere(a)) < nceput(citire(a))
Aceast relaie exprim restricia, c citirea lui a de ctre q nu poate ncepe nainte de terminarea scrierii lui
a de ctre p.
Exemplul 3.5.Rendez-vous. Fie N procese p1,..., pN. Definim n programul fiecrui proces un punct, numit
rendez-vous, pe care procesul nu-l poate trece nainte ca alte procese s ajung la punctul lor propriu de
rendez-vous.
Dac programul procesului pi are forma
<debut_i>;
<rendez-vous>
<continuare_i>;
atunci restriciile de sincronizare se vor exprima dup cum urmeaz:

i, j [1..N]: sfrit(debut_i) < nceput(continuare_j)


Restriciile de sincronizare pot fi exprimate prin urmtoarele dou forme echivalente:
1. Se va impune o ordine de succesiune n timp logic pentru unele puncte ale traiectoriei temporale
ale procesului,
2. Se va impune unor procese o condiie de autorizare a depirii acestor puncte ale traiectoriei lor
temporale.
Punctele privilegiate astfel se vor numi puncte de sincronizare.
Expresia (2) arat, c restriciile de sincronizare pot fi satisfcute impunnd un proces s atepte s
execute o aciune pn cnd o oarecare condiie va fi satisfcut. Aceast noiune de ateptare nu poate fi
exprimat cu ajutorul instrumentarului introdus pn acum; pentru aceasta vom introduce o nou stare
pentru un proces, stare n care procesul se zice n ateptare sau blocat, prin opoziie strii activ,
considerate pn acum n mod implicit. Un proces, care intr n starea de ateptare, plecnd de la un punct
observabil t, oprete progresarea ncepnd cu acest punct i stopeaz executarea aciunilor. n momentul n
care procesul revine n starea activ, el reia execuia sa i contextul su privat restabilete starea pe care
procesul o avea n punctul t (partea neprivat a contextului poate fi modificat de execuia altor procese).
Se numete blocare tranziia activateptare i deblocare tranziia invers. Modalitile de realizare a
blocrii i deblocrii sunt obiectul subparagrafului 3.3.3.
Vom utiliza noiunea de ateptare pentru specificarea sincronizrii proceselor. Aceast specificare se va
produce n dou etape:
1) definirea punctelor de sincronizare pentru fiecare proces,
2) asocierea unei condiii de depire fiecrui punct de sincronizare, condiie exprimat prin intermediul
variabilelor de stare a sistemului.
Vom ilustra acest mod de specificare pentru cele dou exemple precedente. Notm un punct de sincronizare
prin ps, iar condiia de depire asociat prin aut(ps). Dac aceast condiie are valoare TRUE, procesul n
cauz este autorizat s execute instruciunea etichetat cu ps.
Exemplul 3.6:

var f : boolean init false

procesul p

procesul q

scriere(a);

<debut_q>;

f:=true;
<continuare_p>
aut(ps) :

ps :

citire(a)

f:=true

A fost introdus variabila de stare f pentru a exprima condiia procesul p a terminat aciunea scriere(a).
Exemplul 3.7:

var n : integer init 0;

procesul pi
<debut_i>;
n:=n+1
ps:

<continuare_i>

aut(psi):

n=N (i=1,...,N);

Variabila de stare n este n acest caz numrul procesului sosit n punctul de rendez-vous.
43. Probleme de realizare a sincronizrii
Vom ncerca s implementm sincronizarea specificat de condiiile de depire. Pentru aceasta trebuie s
definim un mecanism de ateptare i s introducem noiunea de evenimente memorizate. Un eveniment
memorizat (e) este o variabil, care poate lua dou valori: sosit i non_sosit, valoarea iniial este nonsosit. Asupra evenimentului memorizat sunt posibile dou operaii, care sunt aciuni indivizibile:
e:=<valoare>-- atribuirea imediat a unei valori
ateptare(e).
Operaia ateptare(e), executat de un proces p, are urmtoarea specificaie:
if e = non_sosit then
starea(p) := blocat -- p este trecut n ateptarea lui e
endif
Cnd e ia valoarea sosit, toate procesele care ateptau e trec n starea activ.
Vom ncerca acum s realizm cu ajutorul acestui mecanism sincronizarea pentru cele dou exemple.
var e : eveniment memorizat;

Exemplul 3.8.
procesul p

procesul q

scriere(a);

<debut_q>;

e:=sosit;

ateptare(e);

<continuare_p>

citire(a)

Analiza acestui sistem (care nu conine alte variabile de stare, dect evenimentul memorizat e) poate fi
fcut enumernd traiectoriile temporale posibile. Aceast analiz arat, c sincronizarea este corect
atunci cnd operaiile asupra evenimentului memorizat sunt indivizibile.
var e : eveniment memorizat;

Exemplul 3.9.

n : integer init 0;
procesul pi

<debuti>;
(A) n:=n+1;
(B) if n<N then
ateptare(e)
else
e:=sosit
endif
<continuarei>
O analiz mai atent, analogic celei din exemplul din 3.2.2.3, ne arat c acest program este incorect.
Notnd un registru local al procesului i prin Ri, aciunile (A) i (B) pot fi descompuse dup cum urmeaz:
(1)

load

Ri, n

(2)

ai Ri, 1

-- adunare imediat

(3)

ci Ri, N --comparare imediat

(4)

br () etichet

-- salt dac Ri N

<ateptare (e)>
...
etichet :

...

Presupunem, c toate proceselor sunt n ateptarea punctelor lor de rendez-vous, cu excepia a dou, notate
prin pj i pk. Dac pj i pk vor fi executate pe traiectoria temporal (1j, 1k, 2j,...), atunci fiecare va atribui lui
n valoarea final N-1 i se va bloca, drept rezultat toate procesele se vor bloca pentru un timp indefinit.
Reieind din analiza de mai sus putem concluziona, c implementarea condiiilor de sincronizare nu poate
fi corect realizat numai cu ajutorul operaiilor de ateptare. Consultarea i modificarea variabilelor de
stare, care intervin n aceste condiii, trebuie s fie executate n regim de excludere reciproc. Observaia
dat ne impune s introducem un mecanism de sincronizare, care n mod automat ar asigura acest regim de
funcionare.
44. Monitorul mecanism de sincronizare. Definiii. Exemple de utilizare
Un monitor este constituit dintr-o mulime de variabile de stare i o mulime de proceduri, care utilizeaz
aceste variabile. Unele dintre aceste proceduri, numite externe, sunt accesibile utilizatorilor monitorului;
numele acestor proceduri sunt numite puncte de intrare ale monitorului. Procesele, care utilizeaz
monitorul pentru a se sincroniza, nu au acces direct la variabilele de stare. Monitorul poate fi utilizat doar
prin apelarea procedurilor sale externe; acestea permit blocarea sau deblocarea proceselor conform
specificaiilor problemei. Condiiile de blocare sau deblocare sunt exprimate ca funcie ale variabilelor de
stare, iar mecanismul de execuie a monitorului garanteaz manipularea acestor variabile n regim de
excludere mutual. n fine, un monitor conine un fragment de cod de iniializare, executat o singur dat la
crearea monitorului.
Blocarea i deblocarea proceselor se exprim, n procedurile monitorului, prin intermediul unor condiii. O
condiie este declarat ca i o variabil, dar nu are valoare: o condiie c poate fi utilizat doar prin

intermediul a trei operaii sau primitive, efectul crora este descris mai jos (prin p am notat procesul, care le
execut)
c.ateptare
c.vid

: blocheaz procesul p i l plaseaz n ateptarea lui c

: funcie cu valori booleene (true, dac nu exist nici un proces n ateptarea lui c, altfel false)

c.semnalizare: if non c.vid then <deblocarea proceselor care sunt n ateptarea lui c> endif
Procesele, care sunt n ateptarea unei condiii c, sunt grupate ntr-un fir de ateptare asociat lui c. Putem
spune, c o condiie furnizeaz proceselor un instrument de desemnare a unui astfel fir de ateptare.
Un proces deblocat de c.semnalizare i reia execuia de la instruciunea, care urmeaz imediat primitivei
c.ateptare, care-l blocase. Necesitatea asigurrii excluderii reciproce pentru variabilele de stare impune o
restricie suplimentar mecanismelor de deblocare: atunci cnd un proces p deblocheaz un proces q printro operaie de semnalizare, p i q nu pot fi meninute simultan active. Se va impune blocarea lui p pn n
momentul n care q, la rndul su, se va bloca sau va prsi monitorul. Pentru evitarea unei blocri
indefinite a lui p este necesar ca operaia de transfer a comenzii de la p la q s fie atomar (indivizibil) i
se va garanta, c un proces care a fost temporar blocat este deblocat de operaia semnalizare nainte ca un
nou proces s poat executa o procedur a monitorului.
3.3.3.2. Exemple de utilizare
Exemplul 3.10.
var

sinc: monitor;
fact:

boolean;

term: condiie;
procedura terminare_scriere;
begin
fact:=true;
term.semnalizare
end
procedura debut_citire;
if non fact then
term.ateptare
endif
begin -- iniializare
fact := false
end
end sinc
Monitorul este utilizat dup cum urmeaz:
procesul p
scriere(a);

procesul q

<debut_q>

sinc.terminare_scriere;
<continuare_p>
Exemplul 3.11.

sinc.debut_citire;

citire(a);

rendez-vous : monitor;

var n : integer;
toi_sosii

: condiie;

procedura sosire;
begin
n := n+1;
if n < N then
toi_sosii.ateptare --nu au sosit toate procesele
endif
toi_sosii.semnalizare

-- a sosit i ultimul

end
begin -- iniializare
n:=0
end
end rendez_vous
Programul procesului pi va fi de forma:
procesul pi
<debut i>
rendez_vous.sosire;
<continuare i>
Este foarte important s nelegem funcionarea sincronizrii: procesul, care sosete ultimul la rendez_vous,
execut toi_sosii.semnalizare i deblocheaz unul dintre procesele, care sunt n starea ateptare. Acesta, la
rndul su, execut toi_sosii.semnalizare, deblocnd urmtorul proces i aa mai departe.
45. Implementarea sincronizrii. Probleme-tip
Experiena demonstreaz, c problemele de sincronizare logic ntlnite n practic pot fi reduse, n marea
lor majoritate, la combinaia unui numr mic de situaii elementare, schemele de soluionare ale crora sunt
cunoscute. Seciunile 3.4.2 3.4.5 sunt consacrate studierii acestor probleme-tip, utiliznd instrumentarul
de baz, pus la dispoziie de monitoare. Problemele-tip sunt urmtoarele:
accesarea de ctre o mulime de procese a unei resurse partajate comune,
comunicarea ntre procese,
gestionarea perifericelor i intrrilor-ieirilor tamponate,
sincronizare temporal.
46. Administrarea unei resurse partajate

Considerm o resurs (fizic sau logic) partajat de o mulime de procese. Utilizarea acestei resurse
trebuie s respecte nite reguli de utilizare, destinaia crora const n garantarea unor proprieti
specificate sau restricii de integritate. Aceste restricii sunt specificate pentru fiecare resurs. O
modalitate de garantare a respectrii regulilor de utilizare a unei resurse const n adoptarea urmtoarei
scheme:
modul de folosire a resursei presupune utilizarea obligatorie a procedurilor de acces asociate resursei;
orice tentativ de utilizare, care nu respect acest mod este detectat automat,
procedurile de accesare sunt grupate ntr-un monitor, sau mai multe, programul cruia impune
respectarea restriciilor de integritate.
Cel mai simplu caz este acela al unei resurse pentru care singura restricie de integritate este de a fi utilizat
n excludere reciproc. Simpla grupare a procedurilor sale de acces ntr-un monitor unic garanteaz
respectarea acestor restricii.
47. Alocarea resurselor banalizate
Considerm o resurs pentru care exist un numr fix de N exemplare. Un proces poate accesa la cerere n
uniti din cele N, le poate utiliza i apoi elibera. O unitate, folosit de un proces, se numete alocat
procesului, care o utilizeaz, pentru toat perioada de la accesare pn la eliberare. Toate unitile sunt
echivalente din punctul de vedere al proceselor utilizatoare, vom mai zice c resursa este banalizat.
Zonele-tampon din memoria principal sau pe disc, unitile de band magnetic, etc. sunt exemple de
resurse banalizate.
Vom admite urmtoarele reguli de utilizare:
o unitate poate fi alocat la un moment de timp dat doar unui singur proces,
o unitate poate fi alocat unui proces, care cere alocarea, doar dac ea este liber (nu este alocat nici
unui proces),
o operaie de eliberare este aplicat totdeauna ultimelor resurse, achiziionate de procesul care execut
eliberarea,
o cerere de alocare este blocant n caz de eec (numr insuficient de uniti libere).
Definim dou proceduri cerere i eliberare ale unui monitor. Utilizarea resursei are loc conform schemei
de mai jos.
ps:resurse.cerere(n); -- cerere pentru n uniti
-- ateptare n caz de eec
<utilizarea unitilor primite>
resurse.eliberare(n) -- eliberarea resurselor
Condiia de sincronizare se va scrie pentru orice proces:
aut(ps) : n nlibere
Prima form a unui monitor resurse se va obine utiliznd direct condiia de sincronizare:
resurse: monitor;
var nlibere : integer;

disp

: condiie;

procedura cerere(n);
begin
while n>nlibere do
disp.ateptare;
endwhile;
nlibere:=nlibere-n
end;
procedura eliberare(n);
begin
nlibere:=nlibere+n;
disp.semnalizare

-- deblocare n lan

end;
begin -- iniializare
nlibere:=N
end
end resurse
Nu a fost fcut nici o ipotez despre ordinea proceselor n firul de ateptare al condiiei disp. Drept
consecin, la fiecare eliberare vor fi deblocate toate procesele. Este o soluie greoaie i poate fi foarte
costisitoare, dac exist multe procese. Este preferabil s se programeze n mod explicit administrarea
firului de ateptare a cererilor, ceea ce oblig s avem cte o condiie distinct pentru fiecare proces.
Pentru elaborarea programelor vom introduce un tip discret proces, variabilele cruia permit desemnarea
proceselor.
resurse : monitor
type element : struct
lungime : integer
proc

: proces

end;
var nlibere : integer;
disp

:array[proces] of condiie;

<declaraia firului de ateptare f i procedurilor sale de accesare: introducere, extragere,


primul>
procedura cerere(n);
begin
var e: element;
if n>nlibere then
e.lungime:=n;

e.proc:=p;

-- p este procesul apelant

introducere(e,f);

-- n ordinea de cretere a lungimii

disp[p].ateptare
endif;
nlibere:=nlibere-n
end;
procedura eliberare(n);
var e: element;
begin
nlibere:=nlibere+n;
while primul(f).lungime nlibere do
extragere(e,f);

-- elementul extras = primul (f)

disp[e.proc].semnalizare -- e.proc = procesul deblocat


endwhile;
end;
begin -- iniializare
nlibere:=N;
f:=<vid>
end
end resurse
Aceast soluie este mult mai compact i mai general, deoarece permite o mai bun separare a expresiei
sincronizrii (ceea ce rezult din structura monitorului) de politica de alocare (care este definit de
procedurile de gestionare a firului de ateptare introducere i extragere).
48. Modelul cititorului i redactorului
S considerm un fiier manipulat de procese din dou clase diferite: cititori, care consult fiierul fr a
modifica coninutul lui i scriitori, care pot modifica acest coninut. Fie pentru un moment arbitrar de timp
ncit i nscr numrul de cititori i de scriitori, respectiv, care folosesc o procedur de acces la fiier. Cererea
de asigurare a coerenei fiierului ne impune s respectm urmtoarele restricii:
(nscr=0) i (ncit0) -- fiier n citire
sau

(nscr =1) i (ncit=0) -- fiier n scriere

Fie fich un monitor care asigur respectarea acestor restricii. Vom impune urmtoarea form a acceselor la
fiier:
proces cititor proces scriitor
fich.debut_citire;

fich.debut_scriere;

<acces citire> <acces scriere>

fich.terminare_citire; fich.terminare_scriere;
Procedurile debut_citire, terminare_citire, debut_scriere, terminare_scriere trebuie s asigure
respectarea restriciilor de mai sus. Vom implementa aceste restricii autoriznd depirile; pentru aceasta
este necesar s fie precizate prioritile ntre cititori i scriitori.
Cu titlu de exemplu, presupunem c cititorii au prioritate n faa redactorilor (o scriere nu va fi autorizat,
dac exist cititori n ateptare). Definim urmtoarele variabile de stare:
scr = o scriere este n curs (valoare boolean)
nc = numrul de cititori n ateptare sau n curs de citire
n acest caz, condiiile de depire se vor exprima dup cum urmeaz:
aut(citire) :

scr=false

(nu exist scrieri curente)

aut(scriere): scr=false i nc=0

(nici scrieri nici citiri n curs, nici cititori n ateptarea)

Monitorul, care urmeaz traduce direct aceste condiii.


fich : monitor;
var

scr

: boolean;

nc

: integer;

c_scr, c_cit : condiie;


procedura debut_citire;
begin
nc:=nc+1;
if scr then
c_cit.ateptare;
endif
end
procedura terminare_citire;
begin
nc:=nc-1;
if nc=0 then -- ultimul cititor a terminat
c_scr.semnalizare
endif
end
procedura debut_scriere;
begin
if scr or nc>0 then -- scriere sau citire n curs
c_scr.ateptare
endif;
scr:=true

end
procedura terminare_scriere;
begin
scr:=false;
if nc>0 then -- prioritate cititorilor care ateapt
c_cit.semnalizare
else
c_scr.semnalizare
endif
end
begin -- iniializare
scr:=false;
nc:=0
end
end fich
Pot fi definite i programate i alte reguli de prioritate.
49. Comunicarea ntre procese
Procesele pot comunica prin accesarea unei mulimi de variabile comune. Acest mod de comunicare este
slab structurat i ineficace, deoarece el trebuie s asigure excluderea reciproc a variabilelor. Este utilizat
doar n cazuri speciale, cum ar fi un nucleu de sincronizare, unde excluderea mutual global este redus la
secvene scurte i bine protejate. Pentru cazuri generale sunt utilizate alte moduri de comunicare. Vom
prezenta mai nti o schem de baz pentru comunicarea prin mesaje - modelul productorului i
consumatorului, realizat cu ajutorul monitoarelor (3.4.3.1). O alt posibilitate, descris n 3.4.3.2, const n
a considera operaiile de comunicare ca un fel de mecanisme primitive de sincronizare. n 3.4.3.3
prezentm o aplicaie frecvent de comunicare modelul client-server.
50. Modelul productorului i consumatorului
O schem uzual de comunicare este cea n care un proces (productorul) trimite mesaje unui alt proces
(consumatorul), utiliznd un tampon n memoria comun. Mesajele sunt de lungime fix i capacitatea
tamponului este de N mesaje.
Specificaiile comunicaiei sunt urmtoarele:
un mesaj dat poate fi preluat doar o singur dat dup ce a fost depozitat n tampon,
un mesaj nu trebuie s poat fi pierdut; dac tamponul conine N mesaje nepreluate, nu pot fi depozitate
aici mesaje suplimentare,

o operaie imposibil (depozitare ntr-un tampon plin sau preluare dintr-un tampon vid) blocheaz
procesul, care ncearc s o execute.
Condiiile de depire pot fi exprimate dup cum urmeaz, notnd prin n numrul de mesaje din tampon,
care nu au fost nc preluate:
aut(depozitare) : n < N

-- tamponul nu este plin

aut(preluare) : n > 0 -- tamponul nu este vid


Respectarea acestor restricii este asigurat de un monitor tampon, utilizat dup cum urmeaz:
proces productor
...

proces consumator

...

produce(mesaj_emis);

tampon.preluare(mesaj_recepionat);

tampon.depozitare(mesaj_emis);

consumator(mesaj_recepionat);

Monitorul tampon poate fi elaborat, transcriind n mod direct autorizrile de depire:


tampon : monitor;
var

: 0..N;

non_plin, non_vid : condiie;


<declaraii ale procedurilor depozitare i preluare>
procedura depozitare(m:mesaj);
begin
if n=N then
non_plin.ateptare
endif;
n:=n+1;
introducere(m);
non_vid.semnalizare
end
procedura preluare(var m:mesaj);
begin
if n=0 then
non_vid.ateptare
endif;
preluare(m);
n:=n-1;
non_plin.semnalizare
end;
begin -- iniializare
n:=0;

end
end tampon
Procedurile introducere(m) i preluare(m) definesc politica de gestionare a tamponului i reprezentarea
intern a mesajelor. Un caz frecvent este acela n care mesajele sunt reprezentate de elementele succesive
ale unui tablou, administrat n mod circular. n acest caz mesajele sunt preluate n ordinea depozitrii.
Procedurile de gestionare a tamponului se vor scrie astfel:
type mesaj : <descrierea formatului mesajelor>
ptr

: 0..N-1;

var fa : array[ptr] of mesaj;


top, coad: ptr;
procedura intrare(m:mesaj);
begin
fa[coad]:=m;
coad:=coad+1 mod N
end;
procedura ieire(var m:mesaj);
begin
m:= fa[top];
top:=top+1 mod N
end;
<iniializarea se va completa cu top:=0; coad:=0;>
Aceast schem poate fi extins pentru mai muli productori i consumatori. Drept efect, procedurile
monitorului asigur accesarea exclusiv la mesaje ntre productori i consumtori. Totui, n cazul a mai
muli consumatori schema nu permite direcionarea unui mesaj ctre un consumator anumit: putem doar
garanta, c un mesaj va fi preluat de un consumator (i numai de unul singur) fr a specifica concret de
care.
51. Primitive de comunicare
Schimbul de mesaje ntre procese, n afar de funcia de transmitere a informaiei, poate fi utilizat i pentru
ordonarea evenimentelor n cadrul unor procese distincte, deoarece emiterea unui mesaj precede
ntotdeauna recepia sa. Operaiile de schimb de mesaje pot fi definite ca nite mecanisme primitive i s le
utilizm pentru sincronizarea proceselor.
Primitivele de baz n comunicarea prin mesaje sunt:
emitere(mesaj,destinaie)
recepie(mesaj,origine)
Specificrile acestor primitive trebuie s precizeze:
natura i forma mesajelor,
modul de adresare a proceselor emitoare i destinatare,

modul de sincronizare a acestor procese,


tratarea erorilor.
1) Natura mesajelor
n conformitate cu nivelul de exprimare la care este definit mecanismul de comunicare, mesajele pot fi
specificate de un tip, analogic obiectelor unui limbaj sau prin lungimea fizic a lor. Lungimea poate fi
constant sau variabil. Mai frecvent sunt utilizate mesajele de lungime constant, care pot fi create mai
simplu, mesajele de lungime variabil vor fi transmise prin referin, pasnd adresa fizic sau
identificatorul informaiei transmise.
2) Modul de adresare
Procesele, care fac schimb de mesaje, se pot desemna reciproc prin numele lor (desemnare direct) sau pot
utiliza numele unui obiect intermediar ori cutie potal (desemnare indirect). Aceste nume sunt folosite ca
parametri origine i destinaie. Schema a doua faciliteaz modificarea dinamic a interconexiunilor
proceselor sau chiar componentele unei mulimi de procese, care comunic.
n cazul desemnrii directe parametrul origine a primitivei recepie poate fi interpretat n dou moduri:
fie ca dat: receptorul specific explicit c ateapt un mesaj de la un destinatar special (recepie
selectiv),
fie ca rezultat: receptorul primete un mesaj care i-a fost adresat mpreun cu identitatea emitorului.
n cazul desemnrii indirecte asocierea proceselor cutiilor potale poate fi static sau dinamic. n ultimul
caz, sunt utilizate dou primitive conectare i deconectare pentru ataarea procesului la o cutie potal (n
calitate de receptor) i de abrogare a acestei atari, respectiv. n unele sisteme un receptor sau mai multe
pot fi ataate unei cutii potale date; cutiile potale supuse unor asemenea restricii sunt adesea numite
pori. Este posibil i situaia invers cnd un proces poate fi asociat la mai multe pori distincte. Dac
asocierea ntre procesul receptor i poart este static, un nume de poart specific fr ambiguitate un
proces receptor ca i n metoda desemnrii directe.
3) Moduri de sincronizare
Pentru primitivele de comunicare pot fi specificate mai multe moduri de sincronizare. n caz general,
operaia de recepie blocheaz, n absena mesajului, receptorul. Unele sisteme pun la dispoziie primitive
care dau posibilitatea s se determine dac o cutie potal este vid, ceea ce permite evitarea blocrii.
Pentru emitere sunt utilizate dou moduri de sincronizare:
Schema productor-consumator, n care cutia potal este realizat printr-o zon tampon. Emiterea nu
este blocant, cu excepia cazului n care tamponul este plin. Folosirea tampoanelor de lungime
variabil cu alocarea dinamic a locaiunilor reduce probabilitatea blocrii emitorului.
Schema rendez-vous, n care emitorul este blocat pn la preluarea mesajului de ctre receptor.
Aceast schem poate fi considerat caz limit a precedentei cu lungimea nul a tamponului.
n fine, atunci cnd un proces este asociat n recepie la mai multe pori, poate fi definit un mod de
sincronizare, zis ateptare multipl, n care sosirea unui mesaj la o oarecare din aceste pori deblocheaz
receptorul.
4) Tratarea erorilor
Scopul tratrii erorilor este de a evita blocrile infinite ale proceselor, care se pot produce n diverse
circumstane:
Emiterea unui mesaj cu o destinaie (proces sau poart) inexistent. n acest caz primitiva nu este
blocant; eroarea este tratat prin emiterea unui cod de eroare sau printr-o deviere.

Distrugerea unui proces de la care alte procese ateapt un mesaj sau un rspuns: procesele n ateptare
sunt blocate i recepioneaz un cod de eroare.
Ultima situaie nu este totdeauna detectabil. O tehnic uzual const n stabilirea unui interval de timp
maxim de ateptare a unui mesaj i deblocarea procesului care ateapt la expirarea acestui interval (v.
3.4.5).
Vom ilustra prin cteva exemple reprezentative utilizarea acestor mecanisme de comunicare.
Exemplul 3.12.
Sistemul de operare Thoth [8]. n acest sistem comunicarea folosete desemnarea
direct i sincronizarea prin rendez-vous. Mesajele sunt de lungime constant. Sunt utilizate patru
primitive:
id:=send(message, id_dest)
emite procesului id_dest un mesaj; blocheaz emitorul pn la primirea unui rspuns, transmis n
message. Aceast primitiv indic identitatea procesului care a transmis rspunsul (sau nil, dac
destinatarul nu exist).
id:=receive(message, id_orig)
recepioneaz un mesaj; procesul origine poate s nu fie specificat. Valoarea transmis este identitatea
emitorului.
reply(message, id_orig, id_dest)
trimite un rspuns destinatarului specificat (care trebuie s-l atepte); nu este blocant; fr consecine,
dac rspunsul nu era ateptat.
forward(message, id_orig, id_dest)
aceast operaie non blocant este utilizat de un proces dup recepionarea unui mesaj trimis de ctre
id_orig, pentru ca s impun mesajul s ajung la id_dest, care are acum obligaia de a rspunde lui
id_orig.
Exemplul 3.13.
Sistemul de operare Unix [9]. n sistemul Unix comunicarea ntre procese utilizeaz
tampoane, numite pipes (tuburi), administrate conform schemei productor-consumator. Mesajele
transmise sunt caractere. Un pipe (tub) leag un emitor i un receptor, conexiunea fiind stabilit dinamic.

Exemplul 3.14.
Rendez-vous n limbajul de programare Ada [10, 11]. Limbajul Ada permite definirea
proceselor. Forma sintactic a comunicrilor ntre procese este apelarea procedurii, ns transmiterea
parametrilor i a rezultatelor are loc conform principiului de transmitere a mesajelor cu rendez-vous.
Recepionarea poate fi condiionat (un apel este acceptat doar dac o condiie specificat este satisfcut)
i exist posibilitatea de ateptare multipl.
52. Aplicaii : relaia client-server
O aplicaie curent a comunicrilor ntre procese este relaia client-server. Un proces server are n arj
ndeplinirea unor servicii (executarea unui program predefinit) proceselor client. Pentru aceasta poate fi
utilizat urmtoarea schem:
procesul server

procesul client

ciclu poart_serviciu.emitere(cerere)
poart_serviciu.recepionare(cerere)

<executare serviciu>

...

[poart_client.emitere(rezultat)]
endciclu

...

[poart_client.recepionarere(rezultat)]

Secvenele din parantezele ptrate sunt facultative.


Procesul server este asociat unei pori, unde clienii i depun cererile, trimind cereri; el este blocat atta
timp ct nu exist cereri de servicii n ateptare.
Serviciul cerut poate conine trimiterea la client a rezultatului. n acest caz clientul trebuie s trimit
serverului n cererea sa numrul unei pori la care el se va bloca n ateptarea rezultatului.
Fr a modifica schema de mai sus putem introduce mai multe procese server echivalente, oricare dintre ele
fiind n stare s satisfac o cerere a unui serviciu. Aceste servere n recepie vor fi asociate la una i aceeai
cutie potal.
Modelul din 3.4.2.1 (alocarea resurselor banalizate) i modelul client-server de mai sus sunt reprezentative
pentru dou scheme de obinere a unui serviciu cu ajutorul proceselor ntr-un sistem de operare: apelarea de
procedur ntr-un monitor sau activarea uni proces server ciclic prin emiterea mesajelor. Alegerea ntre
aceste dou scheme este dictat de considerente de eficacitate (schema serverului este preferat, atunci
cnd exist paralelism real ntre client i server) sau de uniformitate a structurii.
53. Administrarea intrrilor-ieirilor
Vom arta cum poate fi integrat administrarea intrrilor-ieirilor n mecanismul monitoarelor. Prezentm
mai nti gestionarea unui periferic izolat, apoi, ca exemplu de aplicaie, principiul unei gestionri
tamponate a intrrilor-ieirilor.
54. Administrarea unui periferic
Fiecrui periferic i este asociat un monitor procedurile externe ale cruia permit executarea intrrilorieirilor la acest periferic. Acest monitor are urmtoarea form general (pentru un sistem mono-utilizator):
perif: monitor;
var ..., sfr_schimb_i,...: condiie;
<declaraiile variabilelor de stare ale perifericului>
...
procedura schimb_i(<parametri>);
begin
<mascarea ntreruperilor>;
if starea preg then
<tratare eroare(perifericul nu este gata)>
endif;
lansare_transfer_i(parametri);

sfr_schimb_i.ateptare;

-- ntrerupere demascat

if starea ok then -- n timpul ateptrii


<tratare eroare(incident de transfer)>
endif;
<demascare ntreruperi>
end;
...
begin
<iniializare>
end
end perif
Procedura lansare_transfer_i pregtete programul pentru schimbul cerut (construirea programului
canalului sau al ADM - Acces Direct la Memorie, innd cont de parametrii schimbului) i lanseaz
execuia sa (instruciunea SIO Start Input Output). Procesele apelante ateapt sfritul transferului
datorit condiiei sfr_schimb_i. Sosirea unei ntreruperi, care marcheaz sfritul schimbului de tip i
provoac n mod automat executarea urmtoarei secvene:
if sfr_schimb_i.vid then <tratarea eroare ntrerupere care nu este ateptat>
else sfr_schimb_i.semnalizare
endif
Pentru un proces care execut o intrare-ieire apelnd o procedur de schimb a acestui monitor, totul se
petrece ca i cum schimbul este sincron: la returul din procedur, informaia a fost efectiv transferat (sau o
eroare a fost detectat i semnalizat). Mecanismul de blocare evit ateptarea activ i procesorul poate fi
utilizat n timpul transferului de un alt proces.

55. Buferizarea imprimrii


Putem elabora acum programul administrrii tamponate a imprimrii, descrise n 3.1. Avem nevoie de trei
tampoane tm1 i tm2 de capacitate N1 i N2 n memoria central i unul pe disc, td, de lungime Ndisc.
Pentru simplitate presupunem, c transferurile se fac cu blocuri constante egale cu o linie. Fiecare tampon
este comandat de un monitor cu aceeai structur care are rolul de a asigura excluderea mutual i
sincronizarea condiiilor tampon plin i tampon vid.
Aceste tampoane, numite tampon1, tampon2 i tampon_disc au aceeai structur cu tamponul descris n
3.4.3, nlocuind N cu N1, N2 i Ndisc, respectiv. Definind tm1, tm2 i td ca tablouri de elemente de
lungimea unei linii i pointerii top i coad locali fiecrui monitor, procedurile de depozitare i preluare pot
fi:
<pentru tamponul 1> <pentru tamponul 2>
procedura intrare(l:linie); procedura intrare(l:linie);
tm1[coad] := l;

tm2[coad] := l;

coad := coad+1 mod N1


procedura ieire(var l:linie);
l := tm1[top];

coad := coad+1 mod N2


procedura ieire(var l:linie);

l := tm2[top];

top := top+1 mod N1

top := top+1 mod N2

n monitorul tampon_disc operaiile de depozitare i preluare sunt intrri-ieiri, care utilizeaz monitorul de
gestionare a discului:
procedura intrare(l:linie);
disc.scriere(l,td[coad]);
coad := coad+1 mod Ndisc
procedura ieire(var l:linie);
disc.scriere(l,td[top]);
top := top+1 mod Ndisc
Programul de intrare-ieire este realizat prin cooperarea a patru procese programul crora este prezentat
schematic mai jos (trei procese ale sistemului de operare i procesul utilizator). Pentru a simplifica
expunerea au fost omise secvenele de tratare a erorilor i am admis, c sistemul funcioneaz n regim
permanent fr limitarea numrului de linii la imprimare. Programele folosesc trei monitoare de gestionare
a perifericelor (tampon1, tampon2 i tampon_disc) i dou monitoare de gestionare a perifericelor (impr i
disc), construite n baza modelului perif, prezentat n 3.4.4.1
proces imprimare linie

proces scriere_disc

proces citire_disc

ciclu ciclu ciclu


tampon2.preluare(l);

tampon1.preluare(l);

impr.scriere(l);

tampon_disc.scriere(l);

endciclu

endciclu

tampon_disc.citire(l);
tampon2.depozitare(l);

endciclu

Imprimarea unei linii este cerut de procedura:


procedura scriere_linie(l:linie);
tampon1.depozitare(l)
Putem constata, c programele de mai sus sunt mult mai simple dect cele care folosesc direct ntreruperile.
Structura modular, introdus de monitoare permite separarea total a gestionrii tampoanelor de cea a
perifericelor. Schimbarea capacitii unui tampon modific doar monitorul care comand acest tampon;
nlocuirea unui periferic cu un altul implic rescrierea doar a monitorului, care comand acest periferic.
56. Sincronizarea temporal
Sincronizarea temporal face ca timpul s intervin nu numai ca mijloc de ordonare a evenimentelor, dar i
ca msur de durat absolut. Acest mod de sincronizare este utilizat n aplicaiile de timp real, care conin
interaciuni cu organe externe (comanda proceselor industriale, de exemplu). Sincronizarea temporal
solicit folosirea unui ceas, realizat prin intermediul unui oscilator cu quartz, care emite impulsuri la
intervale regulate. Aceste impulsuri pot fi utilizate pentru a declana o ntrerupere la fiecare impuls sau
pentru a decrementa n mod automat coninutul unui registru contor, o ntrerupere este declanat atunci
cnd coninutul acestui registru atinge valoare 0.

Vom utiliza a doua metod de funcionare. Unitatea de timp folosit este perioada ceasului.
Pentru rezolvarea problemelor principale de sincronizare temporal poate fi folosit primitiva
suspendare(t), care are ca efect blocarea procesului apelant pentru o durat (fizic) egal cu t uniti de
timp. Prezentm principiul de realizare a acestei primitive cu ajutorul unui ceas.
Pentru rezolvarea acestei probleme vom fi nevoii s ntreinem:
valoarea absolut a timpului (ora absolut), care msoar la orice moment timpul trecut de la o
instan iniial,
un registru, adic o list a proceselor care ateapt deblocarea, ordonat conform timpului absolut de
deblocare.
Toate procesele, care apeleaz primitiva suspendare(t) sunt inserate n registru n poziia, care corespunde
orei sale absolute de deblocare.
Numim ora_de_baz ora absolut a ultimei nnoiri a ceasului, adic a ultimei iniializri a contorului; fie
t_at ultima valoare ncrcat. Ora absolut exact este dat la fiecare moment de timp de relaia
ora_exact = ora_de_baz + t_at - contor
(t_at - contor este timpul care s-a scurs dup ultima nnoire a contorului). De la o ntrerupere de ceas (la
trecerea contorului prin 0), dup ultima nnoire s-a scurs un timp egal cu t_at; ora_de_baz poate, deci, fi
iniializat conform relaiei
ora_de_baz := ora_de_baz + t_at
Variabila ora_de_baz, odat iniializat, va fi corect ntreinut cu condiia ca registrul s nu fie nicicnd
vid; n caz general aceast condiie va fi asigurat introducnd un proces, numit paznic:
procesul paznic
ciclu
suspendare(tmax)
endciclu
n care tmax este un interval foarte mare de timp, paznicul rmnnd pentru toat perioada de lucru n
coada registrului.
Mecanismele descrise sunt realizate ntr-un monitor numit ceas, care are dou intrri: procedura
suspendare (apelat prin ceas.suspendare(t)) i procedura tratare_ntrerupere, pentru tratarea ntreruperii
de ceas (trecerea contorului prin zero). Registrul este realizat cu ajutorul unui fir de ateptare, care conine
descriptorii proceselor. Un descriptor este format din numele procesului i timpul absolut de deblocare;
firul de ateptare este ordonat n ordinea creterii timpului deblocrii.
Presupunem, c ntreruperea de ceas activeaz un proces, unica activitate a cruia const n apelarea
procedurii ceas.tratare_ntrerupere.
ceas: monitor;
type descriptor: struct
i

: proces;

ora_debl

: integer

end;

Problema ar fi uor de rezolvat, dac fiecare proces ar dispune de un ceas propriu: ar fi suficient s se introduc n contor valoarea t i s se atepte ntreruperea
la trecerea prin zero. Realizarea primitivei suspendare cu ajutorul unui ceas unic comun presupune ataarea fiecrui proces a unui ceas virtual.

var contor, t_at;


ora_de_baz, ora_exact: integer
deblocare

: array[proces] of condiie;

<declaraiile firului de ateptare i procedurilor sale de acces>


procedura suspendare(durata:integer);
var proc: descriptor;
begin
ora_exact:=ora_de_baz+t_at-contor;
proc.ora_deblocrii:=ora_exact+durata
proc.i := p;

-- ora absolut a deblocrii

-- p este procesul apelant

intrare(proc,fir)

-- ordonare de ora_deblocrii

if proc=primul(fir) then
t_at:=contor:=durata;
ora_de_baz:=ora_exact;
endif;
deblocare[p].ateptare
end;
procedura tratare_ntrerupere; -- contor n zero
var proc: descriptor;
delta_t:integer;
begin
ieire(proc,fir);

-- primul din firul de ateptare

ora_de_baz := ora_exact+t_at;
if vid(fir) then
delta_t := tmax
else
delta_t := primul(fir).ora_deblocrii ora_de_baz;
endif;
t_at := contor := delta_t; -- deblocarea viitoare
deblocare[proc.i].semnalizare
end;
begin
ora_de_baz := <ora_iniial>;
contor := t_at := tmax;
intrare(paznic,fir)

end
end ceas
Metoda de mai sus (ntreinerea unui registru i a orei absolute) este utilizat pentru realizarea programelor
de simulare discret. Un atare program realizeaz un model n care diferite procese, executate n regim
pseudo-paralel, reprezint activiti care se deruleaz n paralelism real. Timpul utilizat este un timp
simulat, adic o variabil, care reprezint trecerea timpului fizic, respectnd proporionalitatea intervalelor
timpului simulat cu intervalele corespunztoare ale timpului fizic.
57. Gestionarea dinamic a proceselor
Doar n sistemele cele mai simple procesele sunt n numr constant i create odat pentru totdeauna la
iniializarea sistemului. n sistemele concurente, mai ales n cele interactive, procesele sunt comandate
dinamic. Astfel, n Multics, un proces nou este creat odat cu admiterea unui nou utilizator; n Unix, la
executarea fiecrei comenzi. Primitivele de creare i distrugere a proceselor pot fi puse n arja sistemului
de operare sau la dispoziia utilizatorilor. Crearea unui proces presupune alocarea resurselor i iniializarea
contextului, elementele cruia au fost specificate n 3.2.1. Distrugerea unui proces elibereaz toate resursele
care i-au fost alocate.
Primele primitive, propuse pentru gestionarea dinamic a proceselor, au fost fork i join. Istoric i
cronologic, aceste operaii au fost introduse pentru organizarea executrii paralele a programelor pe un
sistem multiprocesoral, noiunea de proces nefiind nc clar. Vom descrie cteva variante ale acestor
primitive.
Fie P o procedur. Instruciunea
id := fork(p),
executat de un proces p (printe), creaz un proces nou q (fiul), care va fi executat paralel cu p. Primitiva
fork prezint ca rezultat identificatorul lui q (sau nil, dac crearea este imposibil). Contextul iniial al lui q
este o copie a lui p, mai puin contorul ordinal, care este fixat la prima instruciune a lui p. Procesul fiu se
termin cu o primitiv, numit exit sau quit, care provoac dispariia sa. Dup ce fork creaz un proces fiu
q, primitiva join q permite procesului printe s fixeze un punct de rendez-vous cu acest fiu. Executarea lui
join q blocheaz procesul printe pn cnd q nu va executa exit. Primitivele fork i join au avantajele i
dezavantajele instruciunii go to din programarea secvenial.
Exemplul 3.15.
n sistemul de operare Unix crearea unui proces poate fi realizat de ctre interpretorul limbajului de comand (shell) sau cu ajutorul
instruciunii fork() de un program. Ultima situaie este prezentat schematic n fig.3.4.

procesul 2

procesul 1

copie

date

date

stiv

stiv

procesul fiu

procesul printe

Fig.4.4. Crearea proceselor cu ajutorul instruciunii fork

Efectul instruciunii fork():

duplicarea procesului printe;

returnarea valorii pid (numrului procesului fiu) n procesul printe;

returnarea valorii 0 n procesul fiu:

procesul printe

procesul fiu

if (fork() == 0)

if (fork() == 0)

codul procesului fiu


else

codul procesului fiu

else
codul procesului printe

codul procesului printe

returnarea pid al procesului fiu ( 0)

returnare 0

Altfel spus, n Unix primitiva fork (fr parametri) creeaz un proces al crui spaiu de lucru este o copie a
spaiului de lucru a creatorului, inclusiv i contorul ordinal. Diferena poate fi determinat consultnd
valoarea returnat de primitiv (0 pentru fiu; identificatorul fiului sau nil pentru printe). O primitiv wait
permite printelui s atepte terminarea execuiei unuia dintre programele fiu (fr a putea alege care
anume, dac exist mai multe). Un proces termin execuia sa cu primitiva exit. Primitiva exec(p) permite
unui proces s schimbe contextul, apelnd o procedur specificat de p.
La lansarea Unix-ului sunt create dou procese: procesul numit Swaper, care administreaz memoria, cu
pid=0 i procesul Init cu pid=1, care creeaz toate celelalte procese.
Ilustrm folosirea primitivelor fork i exec:
...
id := fork();
if id = 0 then -- eu sunt fiul
exec(p)

-- programul fiului

else -- eu sunt printele

if id = -1 then

-- nil : creare imposibil

<tratare eroare>
else
<programul printelui>
endif
endif
Primitiva wait este utilizat dup cum urmeaz:
id := wait(cod)
...

-- blocare pn la terminarea programului unuia dintre fii

-- id = numrul programului fiu terminat, cod = cauza terminrii

58. Sincronizarea n Windows. Procese i fire


Platforma pe 32 de bii pune la dispoziia programatorului instrumente evoluate pentru multiprogramare,
att la nivelul unei mulimi de lucrri, ct i a unei lucrri singulare. Poate s apar ntrebarea CND s fie
utilizat multiprogramarea n cadrul unei singure aplicaii. Rspunsul este foarte simplu: atunci cnd dorim
ca mai multe fragmente de cod s fie executate simultan (pseudosimultan, dac exist mai multe fragmente
dect procesoare). De exemplu, dac dorim ca unele activiti s fie ndeplinite n regim de fond sau
programul s continue s reacioneze la unele evenimente exterioare n timpul ndeplinirii unor calcule
foarte costisitoare. Pot fi aduse i alte exemple. Numim proces n Windows o instan (un exemplar) a
programului, ncrcat n memoria operativ. Aceast instan poate crea fire (thread) - secvene de
instruciuni, care urmeaz a fi executate. Este important s se neleag c n Windows anume firele sunt
executate (nu procesele!), fiecrui proces fiindu-i asociat minimum un fir, numit firul principal al aplicaiei.
Deoarece n realitate exist mult mai multe fire dect procesoare fizice, firele vor fi executate secvenial,
timpul de procesor repartizndu-se ntre fire. Dar viteza mare de execuie i frecvena mare de comutare a
firelor las impresia unei execuii paralele a acestora.
Fr comentarii suplimentare subliniem, c strile elementare ale unui fir sunt aceleai ca i n cazul
proceselor: ales (exe), eligibil (ready) i blocat (wait). Starea blocat este asociat ateptrii unui anume
eveniment. Cnd evenimentul se produce firul este trecut n mod automat n starea eligibil. De exemplu,
dac un fir execut anumite calcule, iar un alt fir este obligat s atepte rezultatele pentru a le salva pe disc,
al doilea fir ar putea utiliza un ciclu de tipul "while(!isCalcFinished ) continue;". Este ns simplu s ne
convingem, c n timpul execuiei acestui ciclu procesorul este ocupat 100% - este cazul ateptrii active.
Astfel de cicluri trebuie evitate prin utilizarea mecanismelor de sincronizare.
n cadrul sistemului de operare Windows exist dou tipuri de fire fire interactive, care execut un ciclu
propriu de prelucrare a mesajelor (de exemplu, firul principal al unei aplicaii) i fire de lucru, care sunt
funcii simple. n ultimul caz execuia firului se ncheie atunci cnd calculele, generate de funcia
respectiv, iau sfrit.
Merit atenie i modalitatea organizrii ordinii de execuie a firelor. Algoritmul FIFO este departe de a fi
cel mai optimal. n Windows toate firele sunt ordonate conform prioritilor. Prioritatea unui fir este un
numr ntreg de la 0 la 31 i este determinat de prioritatea procesului, care a generat firul i prioritatea
relativ a firului. n acest mod se ajunge la o flexibilitate maxim, fiecrui fir punndu-i-se la dispoziie
n caz ideal exact atta timp de procesor, ct are nevoie.

Prioritatea firului poate fi modificat dinamic. Firele interactive, care au prioritatea Normal, sunt executate
n mod deosebit de ctre sistem, prioritatea acestor fire fiind majorat, atunci cnd procesul, care le-a
generat, se afl n planul central (foreground). n rezultat, aplicaia curent reacioneaz mai repede la
cererile utilizatorului.
59. Necesitatea sincronizrii n Windows
Cnd un proces este creat n mod automat este creat firul principal al acestuia. Acest fir poate crea n timpul
execuiei alte fire, care la fel pot crea fire noi i aa mai departe. Timpul de procesor fiind repartizat ntre
fire, fiecare fir lucreaz n mod independent.
Toate firele unui proces mpart resursele comune, de exemplu, spaiul de adrese al memoriei operative sau
fiierele deschise. Aceste resurse aparin ntregului proces, deci i fiecrui fir. Fiecare fir poate s utilizeze
aceste resurse fr nici un fel de restricii. n realitate, din cauza multitaskingului controlat (preemptive
multitasking - la orice moment de timp sistemul poate ntrerupe execuia unui fir i transmite controlul unui
alt fir), se poate ntmpla ca un fir s nu fi terminat nc lucrul cu o resurs comun oarecare, iar sistemul
s treac la un alt fir, care utilizeaz aceeai resurs. Rezultatele pot fi imprevizibile. Asemenea conflicte se
pot produce i n cazul unor fire, care aparin chiar unor procese diferite. Problema poate s apar
ntotdeauna cnd dou sau mai multe fire folosesc o resurs comun. Este necesar un mecanism de
coordonare a lucrului firelor cu resurse comune. n Windows acest mecanism se numete sincronizarea
firelor (thread synchronization).
60. Structura mecanismului de sincronizare n Windows
Mecanismul de sincronizare este un set de obiecte ale sistemului de operare Windows, create i gestionate
program, comune pentru toate firele sistemului (unele pentru firele unui singur proces) i utilizate pentru
coordonarea accesului la resurse. n calitate de resurse pot fi toate obiectele, care pot fi accesate de dou i
mai multe fire un fiier pe disc, un port, un articol al unei baze de date, o variabil global a unui
program, accesibil firelor unui singur procesor, un obiect al dispozitivului interfeei grafice (Graphic
Device Interface), etc.
De obicei, sunt utilizate mecanismele (obiectele) de sincronizare, introduse mai sus: excluderea mutual
(mutex), secia critic (critical section), eveniment memorizat (event) i semaforul (semaphore), fiecare
realiznd metoda proprie de sincronizare. n calitate de obiecte sincronizate pot fi chiar procesele sau firele
(cnd un fir ateapt terminarea execuiei unui proces sau a unui alt fir), fiierele, dispozitivele de
comunicaie, etc.
Sensul mecanismelor de sincronizare const n faptul, c fiecare poate s fie n starea set. Pentru fiecare
mecanism de sincronizare aceast stare poate s aib sens propriu. Firele pot s testeze starea curent a
mecanismului de sincronizare i/sau s atepte modificarea acestei stri, coordonndu-i n acest fel
aciunile proprii. Este foarte important s se sublinieze, c atunci cnd un fir lucreaz cu mecanismele de
sincronizare (le creeaz, le modific starea) sistemul nu ntrerupe execuia firului, pn nu va fi terminat
aceast aciune, adic toate operaiile finite din mecanismele de sincronizare sunt atomare (nu pot fi
ntrerupte).
Menionm de asemenea, c nu exist nici o legtur real ntre mecanismele de sincronizare i resurse.
Mecanismele de sincronizare nu pot interzice accesul nedorit la o resurs, ele doar indic firului momentul
cnd acesta poate accesa resursa, sau cnd acesta trebuie s atepte (de exemplu, un semafor la o intersecie
doar indic cnd este permis trecerea. Cineva poate trece pe rou, dar consecinele pot fi grave).

61. Administrarea obiectelor de sincronizare n Windows


Crearea unui obiect de sincronizare se produce prin apelarea unei funcii speciale din WinAPI de tipul
Create (de exemplu, CreateMutex). Acest apel returneaz descriptorul obiectului (handle), care poate
fi folosit de toate firele procesului dat. Un obiect de sincronizare poate fi accesat i dintr-un alt proces, dac
acest proces a motenit descriptorul obiectului dat, sau folosind funcia de deschidere a unui obiect
(Open). Obiectului, dac el nu este destinat doar pentru uz intern (n interiorul unui singur proces), n
mod obligator i se acord un nume unic. Nu poate fi creat un eveniment memorizat i un semafor cu acelai
nume.
Folosind descriptorul poate fi determinat starea curent a obiectului cu ajutorul funciilor de ateptare. De
exemplu, funcia WaitForSingleObject(x, y) cu doi parametri (primul este descriptorul obiectului, iar al
doilea timpul de ateptare n ms) returneaz WAIT_OBJECT_0, dac obiectul se afl n starea set (adic
nu aparine nici unui fir i poate fi utilizat pentru sincronizare), WAIT_TIMEOUT dac a expirat timpul
de ateptare i WAIT_ABANDONED, dac obiectul de sincronizare nu a fost eliberat nainte ca firul, carel comanda, s se fi terminat. Dac timpul de ateptare este egal cu 0, atunci funcia returneaz rezultatul
imediat, n caz contrar, ateapt intervalul de timp indicat. n cazul n care starea obiectului de sincronizare
va deveni set pn la expirarea acestui timp, funcia returneaz WAIT_OBJECT_0, altfel WAIT_TIMEOUT.
Dac n parametrul timp este indicat constanta simbolic INFINITE, funcia va atepta pn cnd starea
obiectului va deveni set, fr vre-o restricie.
Starea mai multor obiecte poate fi aflat cu ajutorul funciei WaitForMultipleObjects. Pentru ncheierea
lucrului cu un obiect de sincronizare i eliberarea descriptorului se apeleaz funcia CloseHandle. Este
important de tiut, c apelarea unei funcii de ateptarea blocheaz firul curent, adic atta timp ct un fir se
afl n starea de ateptare el nu are acces la procesor.

62. Excluderea mutual


Cum a fost menionat deja, mecanismele de excludere mutual (mutex-ele, de la MUTual EXclusion)
permit coordonarea accesului la o resurs partajat. Starea set a obiectului corespunde momentului de timp
n care obiectul nu aparine nici unui fir i poate fi utilizat, iar starea reset momentului cnd un fir
oarecare controleaz deja mutex-ul. Accesarea va fi permis doar dup eliberare.
Pentru a lega mutex-ul de firul curent trebuie apelat una din funciile de ateptare. Firul, cruia i aparine
mutex-ul, l poate ocupa de mai multe ori, fr autoblocare, ns mai apoi acesta va trebui eliberat tot de
attea ori cu ajutorul funciei ReleaseMutex
63. Evenimentele
Obiectele-evenimente sunt utilizate pentru a informa firele, care sunt n ateptare, despre producerea unui
eveniment. n Windows exist dou tipuri de evenimente cu resetare manual i automat. Resetarea
manual se execut cu funcia ResetEvent. Aceste evenimente sunt folosite pentru informarea mai multor

fire, iar evenimentele cu resetare automat sunt utilizate pentru informarea unui anumit fir, celelalte
rmnnd n ateptare.
Funcia CreateEvent creaz un obiect-eveniment, funcia SetEvent seteaz evenimentul n starea set, iar
funcia ResetEvent reseteaz evenimentul. Funcia PulseEvent seteaz evenimentul, iar dup
semnalizarea firelor, care erau n ateptare (toate n cazul resetrii manuale i doar unul la resetarea
automat), reseteaz obiectul. Dac nu exist fire n ateptare, PulseEvent doar reseteaz obiectul, fr
semnalizare.
64. Semafoarele
Un obiect-semafor este n ultim instan un mutex cu contor. Acest obiect permite s fie ocupat de un
numr anume de fire, dup care ocuparea va fi posibil numai dac unul din fire va elibera semaforul.
Semafoarele sunt utilizate pentru a limita numrul de fire, care lucreaz simultan cu resursa. La iniializare
se specific numrul maxim de fire, la fiecare ocupare valoarea contorului semaforului scade.
65. Seciunile critice
Obiectul-seciune critic permite programatorului s evidenieze un fragment de cod n care firul obine
acces la o resurs partajat, prentmpinnd utilizarea resursei de mai muli utilizatori. Pentru a utiliza
resursa firul va intra mai nti n seciunea critic (apelarea funciei EnterCriticalSection). Dac intrarea a
avut loc, nici un alt fir nu va avea acces la aceeai seciune critic, execuia acestuia fiind suspendat.
Reluarea se va produce n momentul n care primul fir prsete seciunea critic (funcia
LeaveCriticalSection). Diferena de mutex const n faptul c seciunea critic este utilizat numai pentru
firele unui singur proces.
Cu ajutorul funciei TryEnterCriticalSection se poate stabili, dac seciunea critic este liber. Utiliznd
aceast funcie, un proces, fiind n ateptarea resursei, poate s nu se blocheze, ndeplinind operaii utile.
66. Protejarea accesrii variabilelor
Exist o serie de funcii, care permit lucrul cu variabilele globale ale tuturor firelor, fr a ne preocupa de
sincronizare, deoarece aceste funcii singure rezolv problema sincronizrii. Aceste funcii sunt
InterlockedIncrement, InterlockedDecrement, InterlockedExchange, InterlockedExchangeAdd i
InterlockedCompareExchange. De exemplu, funcia InterlockedIncrement incrementeaz valoarea unei
variabile pe 32 bii cu o unitate.
67. Sincronizarea n MFC
Biblioteca MFC conine clase speciale pentru sincronizarea firelor (CMutex, CEvent, CCriticalSection i
CSemaphore). Aceste clase corespund obiectelor de sincronizare WinAPI i sunt derivate de la clasa
CSyncObject. Pentru utilizarea acestor clase trebuie consultai constructorii i metodele lor Lock i
Unlock. n principiu, aceste clase sunt doar un fel de ambalaj pentru obiectele de sincronizare.
O alt modalitate de utilizare a acestor clase const n crearea aa numitelor clase thread-safe. O clas
thread-safe reprezint o anumit resurs n program. Tot lucrul cu resursa este realizat numai prin

intermediul acestei clase, care conine toate metodele necesare. Clasa este proiectat n aa mod, ca
metodele ei s rezolve problema sincronizrii, adic n cadrul aplicaiei s apar ca o simpl clas. Obiectul
de sincronizare MFC este inclus n aceast clas n calitate de membru privat i toate funciile clasei, care
realizeaz accesarea resursei, i coordoneaz lucrul cu acest membru.
Utiliznd funciile Lock i Unlock clasele de sincronizare MFC pot fi utilizate direct, iar n mod indirect
prin funciile CSingleLock i CmultiLock.
68. Exemplu de sincronizare n Windows
Prezentm un exemplu simplu de lucru cu obiectul de sincronizare mutex [22]. Pentru simplitate a fost
utilizat o aplicaie Win32 de consol, dei nu este obligator.
#include <windows.h>
#include <iostream.h>
void main()
{
DWORD res;
// crem obiectul excludere mutual
HANDLE mutex = CreateMutex(NULL, FALSE, "NUME_APLICATIE-MUTEX01");
// dac obiectul exist deja, CreateMutex va returna descriptorul obiectul existent,
// iar GetLastError va returna ERROR_ALREADY_EXISTS
// timp de 20 s ncercm s ocupm obiectul
cout<<"ncerc s ocup obiectul...\n"; cout.flush();
res = WaitForSingleObject(mutex,20000);
if (res == WAIT_OBJECT_0) // dac ocupare s-a terminat cu succes
{
// ateptm 10 s
cout<<"L-am prins! Ateptare 10 secunde...\n"; cout.flush();
Sleep(10000);
// eliberm obiectul
cout<<"Acum eliberm obiectul\n"; cout.flush();
ReleaseMutex(mutex);
}

// nchidem descriptorul
CloseHandle(mutex);
}
Pentru a controla modul de funcionare a mecanismului de excludere mutual se vor lansa dou instane ale
acestei aplicaii. Prima instan va ocupa obiectul imediat i-l va elibera doar peste 10 secunde. Numai
dup aceasta instana a doua va reui s ocupe obiectul. n acest exemplu obiectul de sincronizare este
folosit pentru sincronizarea proceselor, din care cauz n mod obligatoriu trebuie s aib nume.
69. Utilizarea seciunilor critice n Windows
n acest caz seciunile critice sunt utilizate pentru a permite la un moment de timp dat accesul la unele date
importante unui singur fir al aplicaiei, celelalte fire fiind blocate. De exemplu, fie variabila m_pObject
i cteva fire, care apeleaz metodele obiectului referit de m_pObject. Presupunem c aceast variabil
din timp n timp i poate schimba valoarea, valoarea 0 nu este interzis. Fie urmtorul fragment de cod:
// Firul #1
void Proc1()
{
if (m_pObject)
m_pObject->SomeMethod();
}
// Firul #2
void Proc2(IObject *pNewObject)
{
if (m_pObject)
delete m_pObject;
m_pObject = pNewObject;
}
n acest exemplu exist pericolul potenial de apelare m_pObject->SomeMethod() dup ce obiectul a
fost distrus cu ajutorul delete m_pObject, deoarece n sistemele de operare cu multitasking controlat
execuia oricrui fir poate fi ntrerupt n cel mai neconvenabil (pentru firul dat) moment i s nceap
execuia unui alt fir. Pentru exemplul nostru momentul nedorit este atunci cnd firul #1 a testat deja
m_pObject, dar nu a reuit s apeleze SomeMethod(). Execuia firului #1 a fost ntrerupt i a nceput
execuia firului #2. Iar firul #2 reuise deja s apeleze destructorul obiectului. Ce se va ntmpla atunci
cnd firului #1 i se va acorda din nou timp de procesor i va fi apelat SomeMethod() al unui obiect deja
inexistent? Greu de presupus.

Aici ne vin n ajutor seciunile critice. S modificm exemplul de mai sus.


// Firul #1
void Proc1()
{
::EnterCriticalSection(&m_lockObject);
if (m_pObject)
m_pObject->SomeMethod();
::LeaveCriticalSection(&m_lockObject);
}
// Firul #2
void Proc2(IObject *pNewObject)
{
::EnterCriticalSection(&m_lockObject);
if (m_pObject)
delete m_pObject;
m_pObject = pNewObject;
::LeaveCriticalSection(&m_lockObject);
}
Fragmentul de cod inclus ntre ::EnterCriticalSection() i ::LeaveCriticalSection() cu una i
aceeai seciune critic n calitate de parametru nu va fi executat nici o dat n mod paralel. Aceasta
nseamn, c dac firul #1 a reuit s acapareze seciunea critic m_lockObject, ncercarea firului #2
s intre n aceeai seciune critic va conduce la blocarea acestuia pn n momentul cnd firul #1 va
elibera m_lockObject prin apelul ::LeaveCriticalSection(). Invers, dac firul #2 a accesat seciunea
critic naintea firului #1, acesta din urm va fi nevoit s atepte, nainte de a ncepe lucrul cu
m_pObject.
Menionm, c seciunile critice nu sunt obiecte ale nucleului sistemului de operare. Practic, tot lucrul cu
seciunile critice are loc in procesul care le-a creat. Din aceasta rezult, c seciunile critice pot fi utilizate
numai pentru sincronizare n cadrul unui proces. S cercetm mai aprofundat o seciune critic.

70. Structura RTL_CRITICAL_SECTION


Este definit dup cum urmeaz:

typedef struct _RTL_CRITICAL_SECTION


{
PRTL_CRITICAL_SECTION_DEBUG DebugInfo; // Folosit de sistemul de operare
LONG LockCount;

// Contorul de utilizri

LONG RecursionCount;

// Contorul accesrii repetate din firul utilizatorului

HANDLE OwningThread;
HANDLE LockSemaphore;
ULONG_PTR SpinCount;

// ID firului utilizatorului (unic)


// Obiectul nucleului folosit pentru ateptare
// Numrul de cicluri goale naintea apelrii nucleului

}
RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
Cmpul LockCount este incrementat cu o unitate la fiecare apelare ::EnterCriticalSection() i
decrementat cu unu la fiecare apel ::LeaveCriticalSection(). Acesta este primul (adesea i unicul)
control pentru testarea seciunii critice. Dac dup incrementare n acest cmp avem 0, aceasta nseamn c
pn la acest moment nu au avut loc apeluri impare ::EnterCriticalSection() din alte fire. n acest caz
datele pzite de aceast seciune critic pot fi utilizate n regim monopol. Adic, dac seciunea critic
este folosit intensiv de un singur fir, atunci ::EnterCriticalSection() se transform practic n +
+LockCount, iar ::LeaveCriticalSection() n--LockCount. Aceasta nseamn, c folosirea a mai multor
mii de seciuni critice ntr-un singur proces nu va conduce la creterea substanial a utilizrii nici a
resurselor de sistem, nici a timpului de procesor. Ca i concluzie: nu se va face economie pe contul
seciunilor critice. Mult totuna nu vom putea economisi.
n cmpul RecursionCount este pstrat numrul de apeluri repetate ::EnterCriticalSection() din unul
i acelai fir. Dac se va apela ::EnterCriticalSection() din unul i acelai fir de mai multe ori, toate
apelurile vor avea succes. Adic urmtorul cod nu se va opri pentru totdeauna n cel de-al doilea apel
::EnterCriticalSection(), ci va merge pn la capt.
// Firul #1
void Proc1()
{
::EnterCriticalSection(&m_lock);
// ...
Proc2()
// ...
::LeaveCriticalSection(&m_lock);
}
// nc Firul #1
void Proc2()
{

::EnterCriticalSection(&m_lock);
// ...
::LeaveCriticalSection(&m_lock);
}
ntr-adevr, seciunile critice sunt destinate s protejeze datele la accesarea din cteva fire. Utilizarea
multipl a uneia i aceeai seciuni critice de un singur fir nu va genera eroare, ceea ce este normal. Trebuie
doar s avem grij ca numrul de apeluri ::EnterCriticalSection() i ::LeaveCriticalSection() s
coincid i totul va fi n regul.
Cmpul OwningThread conine 0 n cazul seciunilor critice libere sau identificatorul unic al firuluiposesor. Acest cmp este testat, dac la apelul ::EnterCriticalSection() cmpul LockCount, dup
incrementarea cu o unitate, a devenit mai mare ca 0. Dac OwningThread coiincide cu identificatorul unic
al firului curent, atunci valoarea lui RecursionCount crete cu o unitate i ::EnterCriticalSection() este
returnat imediat. n caz contrar ::EnterCriticalSection() va atepta pn firul, care posed seciunea critic,
va apela ::LeaveCriticalSection() de un numr necesar de ori. Cmpul LockSemaphore este folosit, dac
este necesar s se atepte pn seciunea critic este eliberat. Dac LockCount este mai mare ca 0 i
OwningThread nu coiincide cu identificatorul unic al firului curent, atunci firul blocat creaz un obiect al
nucleului eveniment i apeleaz ::WaitForSingleObject(LockSemaphore). Firul posesor, dup
decrementarea cmpului RecursionCount, testeaz acest cmp i dac valoarea lui este 0, iar LockCount
este mai mare ca 0, constat c exist minimum un fir n ateptarea momentului cnd LockSemaphore se
va afla n starea sosit. Pentru aceasta firul-posesor apeleaz ::SetEvent() i un fir oarecare (doar unul)
dintre cele blocate este deblocat i are acces la datele critice.
Windows NT/2000 genereaz o excepie, dac ncercarea de a crea un eveniment a euat. Aceasta este just
att pentru funciile ::Enter/LeaveCriticalSection(), ct i pentru
::InitializeCriticalSectionAndSpinCount() cu bitul cel mai semnificativ al parametrului SpinCount setat.
n cazul sistemului de operare WindowsXP creatorii nucleului au procedat un pic altfel. Aici, funciile
::Enter/LeaveCriticalSection() n loc s genereze o excepie, dac nu pot crea un eveniment propriu, vor
folosi un obiect global, unic pentru toi, creat n avans. n aa mod, n caz de deficien catastrofal a
resurselor de sistem, programul sub comanda lui WindowsXP chiopteaz un timp oarecare mai departe.
ntr-adevr, este foarte complicat s scrii programe, care ar fi n stare s continue lucrul dup ce
::EnterCriticalSection() a generat o excepie. De obicei, chiar dac programatorul a prezis o astfel de
situaie, nu se ajunge mai departe de generarea unui mesaj de eroare i stoparea forat a execuiei
programului. Drept rezultat, WindowsXP ignoreaz bitul cel mai semnificativ al cmpului LockCount.
n sfrit, cmpul LockCount. Acest cmp este folosit doar n sistemele multiprocesorale. n sistemele
monoprocesorale, dac seciunea critic este ocupat de un fir oarecare, putem doar comuta comanda la
aceast seciune i trece n ateptarea evenimentului nostru. n sistemele multiprocesorale exist o
alternativ: s executm de cteva ori un ciclu vid, testnd de fiecare dat dac seciunea critic nu a fost
eliberat (ateptare activ). Dac dup un numr de SpinCount ori seciunea critic nu a fost eliberat,
trecem n starea blocat. Aceast modalitate este mult mai eficient dect comutarea la planificatorul
nucleului i napoi. n WindowsNT/2000 bitul cel mai semnificativ al acestui cmp indic dac obiectul
nucleului, variabila handle a cruia se afl n cmpul LockSemaphore, trebuie creat anticipat. Dac
pentru aceasta nu dispunem de resurse de sistem suficiente, sistemul genereaz o excepie i programul i
poate micora posibilitile funcionale sau chiar termina execuia.

71. Funcii API pentru seciunile critice


Descriem mai jos cteva funcii din API pentru lucrul cu seciunile critice.
Mai nti funciile BOOL InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) i
BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD
dwSpinCount). Completeaz cmpurile structurii lpCriticalSection adresate. Dup apelare seciunea
critic este gata de lucru. Iat pseudocodul funciei RtlInitializeCriticalSection din ntdll.dll
VOID RtlInitializeCriticalSection(LPRTL_CRITICAL_SECTION pcs)
{
RtlInitializeCriticalSectionAndSpinCount(pcs, 0)
}
VOID RtlInitializeCriticalSectionAndSpinCount(LPRTL_CRITICAL_SECTION pcs,
DWORD dwSpinCount)
{
pcs->DebugInfo = NULL;
pcs->LockCount = -1;
pcs->RecursionCount = 0;
pcs->OwningThread = 0;
pcs->LockSemaphore = NULL;
pcs->SpinCount = dwSpinCount;
if (0x80000000 & dwSpinCount)
_CriticalSectionGetEvent(pcs);
}
Funcia DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection,
DWORD dwSpinCount) seteaz valoarea cmpului SpinCount i returneaz valoarea precedent a
acestuia. Amintim, c bitul cel mai semnificativ este responsabil de legarea evenimentului, folosit pentru
ateptarea accesului la seciunea critic dat. Pseudocodul funciei RtlSetCriticalSectionSpinCount din
ntdll.dll este listat mai jos.
DWORD RtlSetCriticalSectionSpinCount(LPRTL_CRITICAL_SECTION pcs, DWORD dwSpinCount)
{
DWORD dwRet = pcs->SpinCount;
pcs->SpinCount = dwSpinCount;

return dwRet;
}
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) elibereaz resursele,
ocupate de seciunea critic. Are urmtorul pseudocod:
VOID RtlDeleteCriticalSection(LPRTL_CRITICAL_SECTION pcs)
{
pcs->DebugInfo = NULL;
pcs->LockCount = -1;
pcs->RecursionCount = 0;
pcs->OwningThread = 0;
if (pcs->LockSemaphore)
{
::CloseHandle(pcs->LockSemaphore);
pcs->LockSemaphore = NULL;
}
}
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection), BOOL
TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) permit intrarea n seciunea
critic. Dac seciunea critic este ocupat de un alt fir, atunci ::EnterCriticalSection() va atepta pn
aceasta va fi eliberat, iar ::TryEnterCriticalSection() va returna valoarea FALSE. Listingurile din
ntdll.dll sunt:
VOID RtlEnterCriticalSection(LPRTL_CRITICAL_SECTION pcs)
{
if (::InterlockedIncrement(&pcs->LockCount))
{
if (pcs->OwningThread == (HANDLE)::GetCurrentThreadId())
{
pcs->RecursionCount++;
return;
}
RtlpWaitForCriticalSection(pcs);
}

pcs->OwningThread = (HANDLE)::GetCurrentThreadId();
pcs->RecursionCount = 1;
}
BOOL RtlTryEnterCriticalSection(LPRTL_CRITICAL_SECTION pcs)
{
if (-1L == ::InterlockedCompareExchange(&pcs->LockCount, 0, -1))
{
pcs->OwningThread = (HANDLE)::GetCurrentThreadId();
pcs->RecursionCount = 1;
}
else if (pcs->OwningThread == (HANDLE)::GetCurrentThreadId())
{
::InterlockedIncrement(&pcs->LockCount);
pcs->RecursionCount++;
}
else
return FALSE;
return TRUE;
}
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection) elibereaz seciunea critic.
Pseudocodul este urmtorul:
VOID RtlLeaveCriticalSectionDbg(LPRTL_CRITICAL_SECTION pcs)
{
if (--pcs->RecursionCount)
::InterlockedDecrement(&pcs->LockCount);
else if (::InterlockedDecrement(&pcs->LockCount) >= 0)
RtlpUnWaitCriticalSection(pcs);
}

72. Clase de seciuni critice

Pentru o utilizare corect a seciunilor critice prezentm mai jos codul claselor seciunilor critice:
class CLock
{
friend class CScopeLock;
CRITICAL_SECTION m_CS;
public:
void Init() { ::InitializeCriticalSection(&m_CS); }
void Term() { ::DeleteCriticalSection(&m_CS); }
void Lock() { ::EnterCriticalSection(&m_CS); }
BOOL TryLock() { return ::TryEnterCriticalSection(&m_CS); }
void Unlock() { ::LeaveCriticalSection(&m_CS); }
};
class CAutoLock : public CLock
{
public:
CAutoLock() { Init(); }
~CAutoLock() { Term(); }
};
class CScopeLock
{
LPCRITICAL_SECTION m_pCS;
public:
CScopeLock(LPCRITICAL_SECTION pCS) : m_pCS(pCS) { Lock(); }
CScopeLock(CLock& lock) : m_pCS(&lock.m_CS) { Lock(); }
~CScopeLock() { Unlock(); }
void Lock() { ::EnterCriticalSection(m_pCS); }
void Unlock() { ::LeaveCriticalSection(m_pCS); }
};
Clasele CLock i CAutoLock sunt utilizate, de obicei, pentru sincronizarea accesrii variabilelor clasei, iar
CScopeLock este destinat, n special, pentru a fi utilizat n proceduri. Compilatorul singur va avea grij
s apeleze ::LeaveCriticalSection() prin intermediul destructorului. Urmeaz un exemplu de folosire a
CScopeLock.

CAutoLock m_lockObject;
CObject *m_pObject;
void Proc1()
{
CScopeLock lock(m_ lockObject); // apelarea lock.Lock();
if (!m_pObject)
return; // apelarea lock.Unlock();
m_pObject->SomeMethod();
// apelarea lock.Unlock();
}
73. Depanarea seciunilor critice
Depanarea seciunilor critice este o ocupaie foarte interesant, dar i dificil. Poi cuta ore i chiar zile n
ir cauza apariiei unei probleme. Erorile, legate de seciunile critice sunt de dou tipuri: de realizare i de
arhitectur. Erorile de realizare pot fi depistate relativ uor i, de regul, sunt generate de utilizarea
incorect (lipsa perechii) a apelurilor ::EnterCriticalSection() i ::LeaveCriticalSection(). Urmeaz un
fragment de cod n care este omis apelul ::EnterCriticalSection().
// n procedur se presupune, c m_lockObject.Lock(); a fost deja apelat
void Pool()
{
for (int i = 0; i < m_vectSinks.size(); i++)
{
m_lockObject.Unlock();
m_vectSinks[i]->DoSomething();
m_lockObject.Lock();
}
}
Apelul ::LeaveCriticalSection() fr ::EnterCriticalSection() va conduce la faptul c chiar
primul apel ::EnterCriticalSection() va stopa execuia firului pentru totdeauna.
n fragmentul de cod de mai jos lipsete apelul ::LeaveCriticalSection():
void Proc()
{
m_lockObject.Lock();
if (!m_pObject)

return;
// ...
m_lockObject.Unlock();
}
n acest exemplu are sens s fie utilizat o clas de tipul CSopeLock. Se mai poate ntmpla ca
::EnterCriticalSection() s fie apelat fr iniializarea seciunii critice cu ajutorul
::InitializeCriticalSection() (de exemplu, n proiectele scrise cu ajutorul lui ATL). n versiunea debug
totul poate lucra foarte bine, iar n versiunea release moare. Aceasta are loc din cauza aa-zisului CRT
(_ATL_MIN_CRT) minimal, care nu apeleaz constructorii obiectelor statice (Q166480,
Q165076). n versiunea ATL 7.0 aceast problem a fost rezolvat. Pot s apar probleme, dac atunci
cnd este folosit o clas de tipul CScopeLock a fost omis identificatorul variabilei, de exemplu,
CScopeLock (m_lock). Compilatorul apeleaz constructorul CScopeLock i imediat distruge acest
obiect fr nume (n conformitate cu standardul!). Adic, imediat dup apelarea metodei Lock() are loc
apelarea metodei Unlock() i sincronizarea nu se produce.
Dintre erorile de arhitectur cea mai frecvent este mbriarea fatal (deadlock, v.5.1.3.3), cnd dou
fire ncearc s acceseze dou i mai multe seciuni critice. Prezentm un exemplu pentru dou fire.
void Proc1()
// Firul #1
{
::EnterCriticalSection(&m_lock1);
// ...
::EnterCriticalSection(&m_lock2);
// ...
::LeaveCriticalSection(&m_lock2);
// ...
::LeaveCriticalSection(&m_lock1);
}
// Firul #2
void Proc2()
{
::EnterCriticalSection(&m_lock2);
// ...
::EnterCriticalSection(&m_lock1);
// ...
::LeaveCriticalSection(&m_lock1);
// ...
::LeaveCriticalSection(&m_lock2);

}
Pot s apar probleme i n cazul copierii unor seciuni critice. Este greu de presupus c codul de mai jos a
fost scris de un programator sntos:
CRITICAL_SECTION sec1;
CRITICAL_SECTION sec2;
// ...
sec1 = sec2;
Din atribuirea de mai sus este dificil s obii foloase. Dar fragmentul urmtor poate fi adesea ntlnit:
struct SData
{
CLock m_lock;
DWORD m_dwSmth;
} m_data;
void Proc1(SData& data)
{
m_data = data;
}
i totul ar fi OK, dac structura SData ar avea on constructor de copiere, de exemplu:
SData(const SData data)
{
CScopeLock lock(data.m_lock);
m_dwSmth = data.m_dwSmth;
}
Presupunem c programatorul a considerat, c este suficient s se ndeplineasc o simpl copiere a
cmpurilor i, n rezultat, variabila m_lock a fost copiat, iar anume n acest moment ea fusese accesat
dintr-un alt fir i valoarea cmpului LockCount este 0. Dup apelul ::LeaveCriticalSection() din acel fir
valoarea cmpului LockCount pentru variabila iniial m_lock a fost decrementat cu o unitate, pentru
variabila copiat rmnnd fr schimbare. Ca rezultat, orice apel ::EnterCriticalSection() nu se va
ntoarce niciodat n acest fir. Va rmne pentru totdeauna n ateptare. Pot exista situaii mult mai
complicate.
Fie un obiect care apeleaz metodele unui alt obiect, obiectele aflndu-se n fire diferite. Apelurile se fac n
mod sincron, adic obiectul #1 transmite execuia firului obiectului #2, apeleaz metoda i se va comuta
napoi la firul su. Execuia firului #1 va fi suspendat pentru toat perioada de execuie a firului obiectului
#2. Presupunem acum, c obiectul #2 apeleaz o metod a obiectului #1 din firul su. Controlul va fi ntors

obiectului #1, dar din firul obiectului #2. Dac obiectul #1 apelase metoda obiectului #2, intrnd ntr-o
seciune critic oarecare, atunci la apelarea metodei obiectului #1 acesta se va bloca pe sine nsui la
intrarea repetat n aceeai seciune critic. Fragmentul de cod care urmeaz vine s exemplifice aceast
situaie.
// Firul #1
void IObject1::Proc1()
{
// Intrm n seciunea critic a obiectului #1
m_lockObject.Lock();
// Apelm metoda obiectului #2, are loc comutarea la firul obiectului #2
m_pObject2->SomeMethod();
// Aici nimerim numai dup ntoarcerea din m_pObject2->SomeMethod()
m_lockObject.Unlock();
}
// Firul #2
void IObject2::SomeMethod()
{
// Apelm metoda obiectului #1 din firul obiectului #2
m_pObject1->Proc2();
}
// Firul #2
void IObject1::Proc2()
{
// ncercm s intrm n seciunea critic a obiectului #1
m_lockObject.Lock();
// Aici nu vom ajunge niciodat
m_lockObject.Unlock();
}
Dac n acest exemplu nu ar fi avut loc comutarea firelor, toate apelurile ar fi avut loc n firul obiectului #1
i nu am fi avut probleme. Exemple de acest gen stau la baza tehnologiei compartimentului COM
(apartments). Nu sunt recomandate apelurile obiectelor, dac au avut loc intrri n seciunile critice.
Primul exemplu din acest subparagraf va fi rescris astfel:
// Firul #1
void Proc1()
{

m_lockObject.Lock();
CComPtr<IObject> pObject(m_pObject); // apelarea pObject->AddRef();
m_lockObject.Unlock();
if (pObject)
pObject->SomeMethod();
}
// Firul #2
void Proc2(IObject *pNewObject)
{
m_lockObject.Lock();
m_pObject = pNewobject;
m_lockObject.Unlock();
}
Accesul la obiect a rmas ca i mai nainte sincronizat, dar apelul SomeMethod() are loc n afara seciunii
critice. Situaia a fost aproape rezolvat. Mai exist o problem mic. S cercetm mai atent Proc2():
void Proc2(IObject *pNewObject)
{
m_lockObject.Lock();
if (m_pObject.p)
m_pObject.p->Release();
m_pObject.p = pNewobject;
if (m_pObject.p)
m_pObject.p->AddRef();
m_lockObject.Unlock();
}
Este evident, c apelurile m_pObject.p->AddRef() i m_pObject.p->Release() au loc n interiorul
seciunii critice. i dac apelarea metodei AddRef() nu genereaz, de obicei probleme, apelarea metodei
Release() poate fi ultimul apel al Release() i obiectul se va autodistruge. n metoda FinalRelease() a
obiectului #2 poate fi orice, de exemplu, eliberarea unor obiecte, care se afl n alte compartimente. Dar
aceasta din nou va conduce la comutarea firelor i poate genera autoblocarea obiectului #1 ca i n
exemplul de mai sus. Pentru a prentmpina aceasta vom folosi aceeai tehnic ca i n Proc1().
// Firul #2
void Proc2(IObject *pNewObject)
{

CComPtr<IObject> pPrevObject;
m_lockObject.Lock();
pPrevObject.Attach(m_pObject.Detach());
m_pObject = pNewobject;
m_lockObject.Unlock();
}
Potenial, acum ultimul apel IObject2::Release() va fi executat dup prsirea seciunii critice. Iar
atribuirea unei valori noi este sincronizat ca i mai nainte cu apelul IObject2::SomeMethod() din firul
#1.
Concluzii:

seciunile critice sunt executate relativ repede i nu cer multe resurse de sistem;

pentru sincronizarea accesrii a mai multor variabile independente este mai bine s fie utilizate
cteva seciuni critice (nu una pentru toate variabilele);

codul unei seciuni critice va fi redus la minimum;

nu este recomandat s fie apelate metode ale unor obiecte strine dintr-o seciune critic.

74. Administrarea proceselor. Realizarea excluderii mutuale. Specificarea problemei


Mecanismele care realizeaz excluderea mutual pentru un set de programe sunt bazate pe un principiu
comun: utilizarea mecanismului de excludere mutual existent deja la un nivel inferior. Drept rezultat, sunt
utilizate variabile comune ale proceselor concurente, iar coerena acestor variabile trebuie ea nsi s fie
garantat. La nivelul de baz (cel al resurselor fizice) exist dou mecanisme elementare: excluderea
mutual la accesarea unui amplasament de memorie i masca ntreruperilor. Aceste dou mecanisme sunt,
n principiu, suficiente pentru toate necesitile. Dar, din considerente de eficacitate, la nivelul resurselor
fizice sau microprogramelor exist dispozitive mai sofisticate, cum ar fi instruciunea Test and Set sau
semafoarele.
Vom preciza mai nti problema excluderii mutuale. Fie {p1, p2,...,pn} o mulime de procese pe care le vom
considera ciclice; programul fiecrui proces conine o seciune critic. Excluderea mutual este asigurat
prin dou fragmente de program (prolog i epilog), care ncadreaz seciunea critic a fiecrui proces.
Presupunem, c fiecare proces, care intr n seciunea critic o prsete ntr-un interval de timp finit.
Soluia trebuie s posede urmtoarele proprieti:
a) excludere mutual: la fiecare moment de timp cel mult un proces execut seciunea critic,
b) absena blocajelor intempestive (care nu sunt la timpul lor): dac n seciunea critic nu se afl vreun
proces, nici un proces nu trebuie s fie blocat de mecanismul excluderii mutuale,
c) toleran la defecte: soluia trebuie s rmn valid i n cazul unor defecte n unul sau n mai multe
procese, care se afl n afara seciunii critice,
d) absena privaiunilor: un proces, care a cerut intrarea ntr-o seciune critic nu trebuie s atepte un timp
infinit (presupunnd, c toate procesele au aceeai prioritate),

e) simetrie: prologul i epilogul trebuie s fie identice pentru toate procesele i independente de numrul
lor.
innd cont de aceste specificaii vom construi o soluie de forma:
<iniializare> -- comun tuturor proceselor
<programul procesului pi>:
ciclu
<prolog>

-- intrare n seciunea critic

<seciunea critic>
<epilog>

-- ieire din seciunea critic

<restul programului>
endciclu
Trebuie s elaborm fragmentele iniializare, prolog i epilog.
75. Excluderea mutual prin ateptare active
nainte de a descrie implementarea excluderii mutuale prin operaii elementare de blocare i deblocare a
proceselor prezentm un mecanism, care permite simularea efectului acestor operaii, meninnd procesele
n stare activ. Un proces n ateptare activ simuleaz blocarea efectund o testare repetat a condiiei de
depire, care poate fi actualizat de alte procese.
76. Algoritmul lui Dekker
Pentru nceput considerm cazul a dou procese p0 i p1. O prim abordare const n reprezentarea condiiei
de ateptare (care este complementar condiiei de depire) printr-o variabil boolean c; vom avea atunci:
c = un proces este n seciunea critic.
Putem propune urmtorul program:
iniializare: c := false;
prolog :

test: if c then
go to test

else
c := true
endif;
<seciunea critic>
epilog :

c := false;

La o analiz mai atent observm (v.3.2.2.3), c dac nu vom face nite ipoteze suplimentare, acest
program nu rezolv problema pus. Iat secvena de intrare n seciunea critic, descompus n instruciuni:
procesul p0

procesul p1

1) test0:

load R0

2)

br (R0=0)

test0

3)

stz

31)

11)

c
21)

test1: load R1
br (R1=0)

stz

test1

(am reprezentat true prin 0, false prin 1, br este operaia de salt condiionat iar stz pune n 0 un
amplasament de memorie). Dac ordinea de execuie este 1, 11, 2, 21, 3, 31 vedem c excluderea mutual
este greit. Problema provine de la faptul c procesul p1 poate consulta c ntre momentul cnd p0 a
consultat c (gsindu-l false) i momentul n care p0 l-a pus pe c n true. Altfel spus, este necesar ca
secvenele de aciuni (1, 2, 3) i (11, 21, 31) s fie executate n mod atomar. Anume acest principiu st la
baza instruciunii Test and Set.
O soluie (algoritmul lui Dekker) poate totui fi construit fr a folosi alte mecanisme de excludere
mutual, n afar de indivizibilitatea accesrii n citire sau actualizarea unui amplasament de memorie.
Prezentm algoritmul pentru dou procese, dei el poate fi extins pentru un numr arbitrar de procese.
Programul folosete trei variabile comune celor dou procese:
var

array [0..1] of boolean;

tur

0..1;

iniializare:

c[0]:=c[1]:=false;
tur:=0;

prolog :

-- pentru procesul i; se va pune j=1-i (cellalt proces)


c[i]:=true;
tur:=j;

test:

if c[j] and tur=j then


go to test
endif;

...
epilog :

-- pentru procesul i
c[i]:=false;

Aceast soluie, demonstrarea validitii creia este propus ca exerciiu, prezint un interes pur teoretic. n
practic sunt utilizate instruciuni speciale care asigur indivizibilitatea secvenelor de testare i modificare.
Ateptarea activ poate fi n egal msur utilizat ca mecanism elementar de sincronizare n cazul unor
alte probleme, diferite de excluderea mutual.
Exemplul 4.1.Relum problema exemplului din 3.3.1 (comunicarea a dou procese printr-un segment
comun). Reprezentm printr-o variabil boolean c condiia de ateptare:
c=procesul p a terminat scrierea n segmentul a
Valoarea iniial c=false. Programele se vor scrie astfel:
procesul p
...
scriere(a);
c:=true

procesul q
...
test: if c

then
go to test

endif;
citire(a)
Putem verifica, c soluia este corect: oricare ar fi ordinea de executare a acestor dou procese, deblocarea
lui q este, n cel mai ru caz, retardat cu un ciclu de ateptare activ. Printre altele, aceast proprietate
rmne adevrat dac vom presupune, c mai multe procese q1, q2,,..., qn ateapt terminarea operaiei de
scriere.
Proprietatea, care asigur validitatea schemei de mai sus, const n faptul c modificarea variabilei c este
efectuat de ctre un singur proces. Notm, c aceast schem a fost deja ntlnit n capitolul 2 la
administrarea intrrilor-ieirilor la CDC 6600: un cuplu de procese comunic prin intermediul unei perechi
de indicatori, fiecare dintre care este actualizat de un proces i consultat de altul. Pentru aceasta este
necesar s se poat executa n excludere mutual instruciunile de testare i modificare.
77. Ateptarea activ n sisteme multiprocesorale: Test & Set
Pentru tratarea cu ajutorul ateptrii active a cazului n care mai multe procese actualizeaz i consult
variabile comune, unele maini au o instruciune, care realizeaz ntr-o manier indivizibil consultarea i
actualizarea unui amplasament de memorie. Aceast instruciune, adesea numit Test And Set (tas), este
utilizat n sistemele multiprocesorale (n sistemele monoprocesor mascarea ntreruperilor este suficient
pentru asigurarea excluderii mutuale).
Fie m adresa amplasamentului de memorie considerat, sau lactul, iar R un registru al procesorului. Prin
convenie, dac lactul este n 0, seciunea critic este liber, iar dac este 1 ea este ocupat. Efectul lui
Test And Set este descris mai jos (Mp[m] desemneaz amplasamentul de memorie cu adresa m):
tas R, m : <blocare acces la Mp[m]>
R:=Mp[m]
Mp[m]:=1
<eliberare acces la Mp[m]>
Excluderea mutual prin ateptare activ poate fi programat cu ajutorul urmtoarelor secvene:
iniializare

: stz

prolog : tas

R, m

br(R0)
epilog : stz

-- Mp[m]:=0

$-1

-- test iterat

78. Semaforul instrument elementar pentru excluderea mutual. Definiii


Un semafor s este constituit prin asocierea unui contor cu valori ntregi, notat s.c., i a unui fir de ateptare,
notat s.f. La crearea semaforului contorului i se atribuie o valoare iniial s0 (s00), i firul de ateptare s.f.
este vid. Un semafor servete la blocarea proceselor ateptnd s se produc o condiie pentru deblocarea
lor; procesele blocate sunt plasate n s.f. Mai multe procese pot fi sincronizate prin semafoare, care aparin
prii comune a contextului lor. Un procesor poate fi manipulat doar cu ajutorul a dou operaii P(s) i V(s),
numite primitive. Valoarea contorului i starea firului de ateptare sunt inaccesibile, chiar i pentru citire.

Fie p un proces care execut P(s) sau V(s), iar q un proces care se afl n firul de ateptare s.f. Algoritmul
primitivelor este urmtorul:
P(s): V(s):
s.c.:=s.c.-1;

s.c.:=s.c.+1;

if s.c.<0 then if s.c.0 then


stare(p):=blocat;

extragere(q,s.f.);

introducere(p,s.f.)

stare(q):=activ

endif endif
Aceste operaii sunt executate n excludere mutual. Modalitatea de realizare efectiv a semafoarelor i a
primitivelor P i V este descris n 4.3. Operaiile introducere i extragere permit inserarea unui proces ntrun fir de ateptare sau, respectiv, extragerea. Nu facem aici nici un fel de ipoteze despre politica de
gestionare a firului de ateptare: algoritmii de sincronizare trebuie s fie independeni. Politica aleas n
cazul alocrii unui procesor este discutat n 4.3, la fel i detaliile legate de operaiile de blocare i
deblocare.
Exemplul 4.2.Funcionarea unui semafor poate fi comparat cu lucrul unui magazin accesul n care este
admis doar dac la intrare exist couri libere (sau crucioare) n care cumprtorii i duc marfa (intrarea
fr co este interzis). La deschiderea magazinului un anumit numr de couri libere sunt puse la
dispoziia cumprtorilor la intrare. Un cumprtor ia un co liber, intr n magazin i i alege marfa, iar
dac la intrare nu exist un co liber, cumprtorul este obligat s atepte ntr-un fir de ateptare (operaia
P). La ieire cumprtorul pune coul de unde l-a luat (operaia V).
Doar executarea primitivei P poate bloca un proces, acesta va putea fi deblocat doar de un alt proces, care a
executat primitiva V pe acelai semafor. Executarea operaiei V nu este blocant.
79. Semaforul Proprieti
Proprietile principale ale sincronizrii cu ajutorul semafoarelor pot fi deduse din cteva relaii invariante:
relaii verificate iniial i care rmn neschimbate dup executarea primitivelor P i V un numr arbitrar de
ori.
1) Fie, pentru un semafor s:
np(s) numrul total de execuii a operaiei P(s),
nv(s) numrul total de execuii a operaiei V(s).
Are loc relaia:
s.c. = s0 np(s) + nv(s)

(1)

deoarece valoarea iniial a lui s.c. este s0, fiecare operaie P(s) scade din aceast valoare o unitate, iar V(s)
adaug 1.
Aceste operaii, fiind executate n excludere mutual, nici o modificare nu este pierdut.
2) Fie nbloc(s) numrul proceselor blocate n s.f. Are loc relaia:
nbloc(s) = if s.c. 0 then 0 else s.c. endif (2)
care poate fi de asemenea scris
nbloc(s) = max(0, s.c.)

(21)

Relaia (2) iniial este adevrat. Tabelul de mai jos, care indic efectul operaiilor P(s) i V(s) asupra
valorii variabilei nbloc, arat c aceste operaii las relaia (2) invariant.
s.c.<0

s.c.=0

s.c.>0

Efectul operaiei P(s)

+1

+1

--

Efectul operaiei V(s)

-1

--

--

3) Relaia (2) poate fi scris sub o alt form, care ne va fi util mai departe. Fie nf(s) numrul de treceri
de ctre procese a primitivei P(s), adic suma numrului de executri a lui P(s) fr blocare i a
numrului de deblocri realizate de ctre V(s). Vom avea n acest caz:
nbloc(s) = np(s) nf(s).
Introducnd aceast valoare n (21) obinem:
- nf(s) = max(-np(s), -s.c.-np(s)), sau
nf(s) = min(np(s), s.c.+np(s)).
n fine, utiliznd valoarea lui s.c. din (1), avem:
nf(s) = min(np(s), s.c.+nv(s)). (3)
80. Realizarea excluderii mutuale cu ajutorul semafoarelor
Prezentm o schem, care rezolv problema excluderii mutuale pentru n procese. n cazul n care nu se fac
ipoteze speciale despre gestionarea firului de ateptare, nu se garanteaz lipsa privaiunilor (blocrilor
indefinite).
iniializare

semafor mutex init 1

prolog :

P(mutex),

epilog :

V(mutex).

S ne convingem, c soluia prezentat este n conformitate cu specificaiile din 4.1.1. Trebuie s verificm
proprietile a, b i c au loc.
Fie nc numrul de procese, care se afl n seciunea critic la un moment concret de timp. Avem:
nc = nf(mutex) nv(mutex)

(4)

Proprietile n cauz pot fi verificate aplicnd semaforului mutex relaia (3) din 4.1.3.2:
nf(mutex) = min(np(mutex), 1+nv(mutex))

(5)

a) Excluderea mutual
Din (5) avem:
nf(mutex) 1+nv(mutex)
i, utiliznd (4), obinem nc 1: excluderea mutual este asigurat.
b) Absena blocajelor
Presupunem, c nici un proces nu se afl n seciunea critic. Vom avea n acest caz nc = 0, sau
nf(mutex) = nv(mutex) sau nc
nf(mutex) 1+nv(mutex)

Vom avea conform relaiei (5):


nf(mutex) = np(mutex) sau
nbloc(mutex) = 0
Deci, proprietatea b este prezent, ca i proprietatea c, deoarece nu s-a fcut nici o ipotez despre starea
proceselor, dac ele nu se afl n seciunea lor critic.
1). Seciuni critice incorporate. Blocaje
Vom considera dou procese p i q pentru care programul conine dou seciuni critice distincte,
corespunztoare utilizrii a dou resurse critice distincte.
procesul p
(1)
(2)

procesul q

...

...

P(mutex1)

(11)

...

...

P(mutex2)

(21)

...

...

V(mutex2)
...
V(mutex1)

P(mutex2)
P(mutex1)
V(mutex1)

...
V(mutex2)

Dac traiectoria temporal de execuie a proceselor p i q ncepe cu (1, 11, 2, 21), se va ajunge la o situaie
n care ambele procese sunt blocate pentru un timp infinit, deoarece fiecare dintre procese poate fi deblocat
doar de ctre cellalt. Aceast situaie este numit blocare sau mbriare fatal (eng. deadlock, fr. treinte
fatale).
2). Ateptare infinit n seciunea critic sau impas
Validitatea soluiei propuse se bazeaz pe presupunerea, c toate procesele prsesc seciunea critic n
timp finit. Numai ce am stabilit, c aceast ipotez poate fi infirmat dac seciunile critice se intersecteaz.
Pot fi i alte cauze, care conduc la o ateptare infinit. Astfel, blocarea, incorectitudini sau ciclri infinite
ntr-un proces, care se afl n seciunea critic, pot paraliza toate procesele concurente cu procesul dat. n
cazul unor seciuni critice globale (care prezint interes pentru toi utilizatorii), realizate pentru un sistem
de operare, pot fi propuse urmtoarele soluii:
oricrui proces, care execut o seciune critic global, i se atribuie, pe toat durata acestei execuii, un
statut special, care i confer anumite drepturi particulare: prioritate nalt, protecie contra distrugerii,
etc.
un orologiu de gard este armat la intrarea unui proces n seciunea critic; dac procesul nu prsete
seciunea critic dup un interval de timp predefinit, sistemul de operare foreaz ieirea procesului i
elibereaz astfel seciunea critic. Aceast soluie nu este cea mai bun, or datele globale, manipulate n
seciunea critic, pot s devin incoerente. Este necesar s se ofere posibilitatea restabilirii acestor date
la o stare anterioar, considerat valid, ceea ce implic salvri periodice.
3). Privaiune
Algoritmul excluderii mutuale garanteaz intrarea exact a unui proces n seciunea critic, dac mai multe
procese ncearc acest lucru, cnd seciunea critic este liber. Se poate ntmpla ca un proces particular s
fie reinut pentru un interval de timp nedefinit: acest fenomen se numete privaiune, pe care o vom
rentlni atunci cnd vom studia alocarea resurselor. ntradevr, procesele candidate la intrare, ateapt n

firul de ateptare mutex.f i ordinea lor de deblocare (prin V(mutex)) depinde de politica de gestionare a
acestui fir, despre care nu s-a fcut nici o ipotez.
Pentru cazul cel mai frecvent, cnd firele de ateptare a semafoarelor sunt gestionate conform ordinii prim
sosit prim servit fr prioritate, riscul de privaiune este eliminat
ntradevr, dac presupunem c execuia unei seciuni critice dureaz totdeauna un interval finit de timp,
orice proces, dup o perioad finit de timp, va deveni cel mai vechi n firul su de ateptare.
81. Funcionarea i structura unui nucleu de sincronizare. Strile unui proces. Fire de ateptare
Noiunea de proces i operaiile asociate nu fac, de obicei, parte din setul de baz al calculatorului. Ele vor
fi implementate cu ajutorul unor programe i/sau microprograme, care formeaz nucleul de administrare a
proceselor. n cadrul descrierii unui sistem de operare cu ajutorul mainilor abstracte ierarhice (v. cap.9),
nucleul constituie nivelul cel mai inferior, realizat direct pe maina fizic. Maina abstract, realizat astfel
poate fi numit o main a proceselor, care posed, n afara setului de instruciuni de baz, primitivele care
permit crearea, distrugerea i sincronizarea proceselor. Ca i orice main abstract, maina realizat n
acest mod ascunde unele proprieti ale mainii fizice. Astfel:
noiunea de proces, care este echivalent cu cea de proces virtual, ascunde utilizatorilor nucleului
mecanismul de alocare a procesoarelor fizice. La un nivel superior nivelului nucleului chiar i numrul
procesoarelor nu intervine dect doar asupra performanelor sistemului i nici ntr-un fel asupra
structurii sale logice,
primitivele de sincronizare, realizate de nucleu, ascund mecanismele fizice de comutare a contextului,
de exemplu, cele oferite de ntreruperi.
Structura unui nucleu de sincronizare depinde, printre altele, de specificaiile mainii fizice (gestiunea
ntreruperilor, structura cuvntului de stare, sistem mono- sau multiprocesoral, etc.) i de specificaiile
mainii abstracte care trebuie realizate, ndeosebi de mecanismul de sincronizare ales. Este, totui, posibil
de evideniat cteva caracteristici comune ale acestei structuri, pe care le vom prezenta nainte de a descrie
o realizare concret.
Am considerat pn acuma c un proces se poate afla n dou stri: activ sau blocat. Luarea n consideraie
a alocrii fizice a unui procesor ne impune s descompunem starea activ n dou stri noi. Un proces activ
se numete ales, dac el este n curs de execuie pe un procesor fizic; el se numete eligibil dac nu poate fi
executat din cauza lipsei unui procesor disponibil. Aceast evideniere este legat doar de disponibilitatea
procesorului i nu are vre-un suport logic. Figura 4.1 descrie strile unui proces i tranziiile lui.
Tranziiile 3 i 4 (blocare i deblocare) sunt tranziiile interne, datorate sincronizrii proceselor.
Tranziiile tehnologice 1 i 2 sunt datorate alocrii procesoarelor fizice proceselor. n particular, tranziia
2 se produce atunci cnd algoritmul de alocare ia procesorul de la un proces, care nc mai are nevoie de el.
Aceast operaie este numit retragere (eng. preemption, fr. rquisition) a procesorului.
Administrarea proceselor face apel la fire de ateptare. Astfel, fiecrei cauze distincte de blocare (semafor,
condiie ntr-un monitor, etc.) i se asociaz un fir de ateptare pentru a stabili o ordine a proceselor blocate.
Mai mult, procesele eligibile sunt meninute ntr-un fir special de ateptare, gestionarea cruia permite
implementarea unei politici de alocare a procesoarelor fizice. Dac presupunem, c viitorul proces ales este
totdeauna primul din firul proceselor eligibile, algoritmul de alocare poate fi definit
cu ajutorul algoritmului de inserare n firul proceselor eligibile,
cu ajutorul algoritmului care determin retragerea procesoarelor fizice.

eli
gib
il
(re
ad
y)

(1
)
(2
)
(4
)

ales
(ex
e)

(3
)
blo
cat
(wa
it)

Fig.4.1.
Strile unui
proces

Mulimea programelor, care realizeaz aceti algoritmi se numete planificator (eng. scheduler, fr.
ordonnanceur). Programul, care realizeaz alegerea propriu-zis se numete dispecer (eng. dispatcher, fr.
distributeur). Schema general a firelor de ateptare ale proceselor este prezentat n fig.4.2. Deplasarea
proceselor ntre aceste fire corespunde schimbrii strii.
planifi
cator

fire de
procese
proces
dispe
firul
blocate
ales
cer
proceselor
Fig.4.2. Fire de ateptare ale proceselor,
eligibile
administrate de nucleul
sistemului de operare

82. Administrarea contextelor i schemele primitivelor


1) Coninutul contextului
Operaia de alocare a procesorului fizic impune pstrarea pentru fiecare proces a unei copii a contextului.
Aceast copie a contextului descrie starea procesorului pentru procesul considerat. n acest scop fiecrui
proces i se asociaz o mulime de informaii rezidente n memorie i numit vector de stare, bloc de
control al procesului sau blocul contextului, care conine:
informaiile despre starea procesorului, necesare la realocarea lui (coninutul cuvntului de stare,
registrelor),
valorile atributelor procesului (prioritate, drept de acces),
pointeri la spaiul de lucru al procesului (segmentele procedur i date, stiva de execuie),
informaii de gestiune (starea, legturile de nlnuire).
O descriere mai detaliat a blocului contextului unui proces este dat n 4.3.
2) Organizarea nucleului
Execuia programelor nucleului este declanat n dou moduri (fig.4.3):

prin apelarea unei primitive de administrare a proceselor (creare, distrugere, sincronizare, etc.); aceste
primitive sunt realizate sub form de apel al supervizorului,
printr-o ntrerupere: programele de tratare a ntreruperilor fac parte din nucleu, deoarece ntreruperile
sunt traduse n operaii de sincronizare i sunt invizibile la nivelurile superioare.
n ambele cazuri, mecanismul de intrare n nucleu conine salvarea automat a cuvntului de stare i,
eventual, a registrelor procesorului, care execut apelul supervizorului sau care trateaz ntreruperea. n
dependen de organizarea calculatorului, aceste informaii sunt salvate ntr-un amplasament fix (legat de
nivelul ntreruperii sau de apelul supervizorului) sau ntr-o stiv (ndeosebi n cazul sistemelor
multiprocesorale). Prile contextului, salvate n acest fel, sunt cele ale proceselor alese pentru procesorul
n cauz, n momentul ntreruperii sau apelrii supervizorului.
Programele primitivelor i cele de tratare a ntreruperilor manipuleaz blocurile contextului i firele
proceselor. Pentru asigurarea coerenei informaiilor aceste programe trebuie executate n excludere
mutual. Executarea unui program al nucleului se termin n toate cazurile prin realocarea procesorului sau
procesoarelor, adic prin apelarea dispecerului. Deoarece este posibil ca firul de ateptare a proceselor alese
s fi fost modificat de execuia primitivelor, noul proces ales poate s difere de ultimul proces ales pentru
procesorul ntrerupt.
alocare
proceso
r

apelare
pro
supervizo
ces
r
progr
amul
nucle
perife
ului
lansa
ntrerup
rice,
reFig.4.3. Comunicarea
eri
cu
un
ceasu
nucleu de sincronizare
l

Programul unei primitive a nucleului are urmtoarea schem general:


prolog;

-- salvarea contextului i intrarea n seciunea critic

control;

-- verificarea drepturilor i a parametrilor

<corpul programului>
alocare_procesor;

-- manipuleaz firele proceselor

-- programul dispecer i ieirea din seciunea critic

Secvena prolog, comun tuturor operaiilor, salveaz contextul procesului, care execut operaia, i asigur
intrarea n seciunea critic. Secvena control verific drepturile procesului apelant de a executa primitiva i
validitatea parametrilor transmii. Detaliile depind de primitiv. Secvena alocare_procesor este programul
dispecerului: ea realizeaz realocarea procesorului i ieirea din seciunea critic.
Diferena ntre sistemele mono- i multiprocesorale se manifest n mod esenial la realizarea excluderii
mutuale i alocrii procesorului (secvenele prolog i alocare_procesor).
Tratarea ntreruperilor de ctre nucleu trebuie s fie coordonat cu mecanismele de sincronizare alese. De
obicei sunt considerate dou scheme de baz:
1) Asocierea unui proces, care trateaz fiecare ntrerupere. Doar acest proces se va afla n ateptarea unei
ntreruperi anume, existnd pentru aceasta o instruciune special.
2) Asocierea unei operaii de deblocare (semnalizare asociat unei condiii, V la un semafor, etc.) la o
ntrerupere.

Problemele de mascare i de prioritate a ntreruperilor sunt, de obicei, tratate asociind prioriti proceselor.
83. Realizarea unui nucleu de sincronizare. Organizarea general intrebarile de mai jos
84. Realizarea unui nucleu de sincronizare. Interfeele
a) Gestionarea proceselor
Procesele pot fi create i distruse n mod dinamic, i sunt organizate ierarhic conform relaiei de legtur
(v.3.5). Un proces este creat cu ajutorul primitivei:
creare(p, context iniial, atribute)
Atributele unui proces conin prioritatea (exprimat printr-un ntreg) i drepturile de a executa anumite
operaii. Contextul iniial specific starea iniial a cuvntului de stare i a registrelor procesorului, i a
spaiului de lucru asociat procesului (stiva, date proprii). Procesul este creat n starea eligibil. Numrul su
p (numele) este returnat ca rezultat (valoarea nil, dac crearea este imposibil). O funcie
determin_numr_propriu permite unui proces s afle numrul su propriu.
Primitivele care urmeaz pot fi aplicate unui proces existent i pot fi executate doar de procesul-printe.
Procedura distrugere poate fi utilizat de ctre un proces pentru a se autodistruge. Deci, distrugere(p) va
distruge toate procesele desemnate de procesul p i toi descendenii acestora.
Procedura suspendare(p) ntrerupe execuia unui proces p, plasndu-l ntr-un fir de ateptare special.
Execuia lui p poate fi reluat doar cu ajutorul primitivei reluare(p). Primitivele suspendare i reluare sunt
introduse din considerente de securitate, n special pentru a permite monitorizarea unui proces de ctre
procesul-printe.
Utilizarea primitivelor creare, distrugere, suspendare i reluare este condiionat de un drept, care
figureaz n atributul drepturi al procesului.
b) Sincronizarea
Procesele sunt sincronizate cu ajutorul monitoarelor. Gestiunea ntreruperilor este integrat n mecanismul
monitoarelor: o ntrerupere este asociat unei condiii. Specificarea primitivelor, care difer un pic de cea
din 3.3, este precizat n 4.3.2. Monitoarele sunt declarate n programele proceselor; un monitor este creat
la compilarea programului, unde el este declarat, i este mai apoi utilizat conform regulilor, definite de
limbajul de programare utilizat (care nu este aici specificat).
85. Realizarea unui nucleu de sincronizare. Structuri i algoritmi
Din momentul crerii sale unui proces i se asociaz un numr fix (process handler), care servete la
desemnarea lui i permite accesarea blocului su de context. Blocul de context conine urmtoarele
cmpuri:
Csp

: zona de salvare a cuvntului de stare a procesorului,

Reg

: zona de salvare a registrelor generale ale procesorului,

Stare : valoarea strii procesului (eligibil, blocat, ...),


Prio

: prioritatea procesului,

Drepturi

: drepturile procesului,

Fire, etc.

: legturi de nlnuire n ierarhia proceselor,

Suc, etc.

: legturi de nlnuire n firele de ateptare (FA).

Administrarea proceselor utilizeaz fire de ateptare, ordonate n ordinea de descretere a prioritilor i


comandate de un set de proceduri de accesare, specificate mai jos (p specific un proces, f un fir de
ateptare):
introducere(p, f) Introduce p n f, n elementul lui f care corespunde prioritii procesului i n ordinea
sosirii pentru procesele cu aceeai prioritate.
primul(f)
modific f.

ntoarce numrul (numele) procesului din vrful lui f (nil dac f este vid); nu

ieire(p, f)

Extrage din firul f primul proces, numrul acestuia fiind pus n p (nil dac f este vid).

extragere(p, f)
Extrage din firul f procesul cu numrul p specificat, oricare ar fi elementul n
care acesta se afl; pune n p valoare nil, dac procesul nu exist n firul f.
vid(f)

Funcie boolean cu valoarea adevrat, dac firul f este vid, fals n caz contrar.

Figura 4.4 prezint schematic organizarea unui fir de ateptare a proceselor.


legtur de
.
nlnuire
Csp[i]
.
.
Bloc de
context

Reg[i]
Stare[i]
Drepturi[i]
Prio[i]

.
.
.

blocul
Fig.4.4. Organizarea contextului
unui FA de i
procese

legturi de
nlnuire
context
n n FA
memorie

86. Realizarea unui nucleu de sincronizare. Realizarea monitoarelor.


Monitorul, descris mai jos, este inspirat de realizarea folosit n limbajul Mesa [12], care a fost validat de
o vast experien de utilizare. n raport cu noiunea clasic de monitor (3.3.3), aceast realizare prezint
urmtoarele diferene:
1) Semantica primitivei semnalizare. Specificarea iniial a primitivei c.semnalizare precizeaz c unul
din procesele care sunt n ateptarea condiiei c (dac exist) este imediat deblocat, ceea ce implic
trecerea temporar n starea blocat a procesului care execut semnalizare. n specificarea prezent
procesul deblocat este simplu trecut n starea eligibil i trebuie s intre n monitor; el se afl, deci, n

competiie cu alte procese, care ateapt s intre n monitor, i nu este garantat c va fi imediat ales.
Condiia, care provocase deblocarea, poate fi modificat nainte ca procesul deblocat s-i reia execuia
n monitor. Pentru aceast nou interpretare trebuie s fie modificat forma punerii n ateptare. O
construcie de forma
if continuare_non_posibil then
c.ateptare
endif
devine n acest caz
while continuare_non_posibil do
c.ateptare
endwhile
Dei aceast construcie introduce un risc de privaiune, ea prezint o serie de avantaje de ordin practic. Ea
evit o comutare a contextului, cu preul unei evaluri suplimentare a condiiei. Dar principalul este c ea
permite definirea simpl a unor posibiliti suplimentare utile (deblocare multipl, ntrzieri de control sau
de gard), precizate mai jos. n fine, trebuie s notm, c verificarea validitii monitorului este
simplificat, deoarece condiia de depire (continuare_posibil) este consultat n timpul deblocrii:
procesul care execut semnalizare poate s se mulumeasc cu garantarea unei condiii mai slabe dect
condiia de depire.
2) Deblocare multipl. Problema deblocrii multiple poate fi rezolvat uor introducnd o primitiv nou
c.difuzare_semnal efectul creia se exprim astfel:
while c.non_vid do
c.semnalizare
endwhile
Fiind dat, c toate procesele deblocate vor testa din nou condiia i cer din nou acces la monitor, aceast
primitiv va avea evident efectul ateptat.
3) ntrziere de gard. Din probleme de securitate, n special pentru tratarea blocajelor, poate fi util s se
asocieze o ntrziere de gard condiiei unui monitor. Aceast ntrziere este egal cu durata maxim de
blocare a unui proces ntr-un fir de ateptare asociat condiiei date. La expirarea ntrzierii de gard va
fi efectuat o tratare specificat. Aceast tratare poate consta n simpla deblocare a procesului (care va
testa din nou condiia de depire) sau transferul su ntr-un fir de ateptare special (v.4.3.2.3).
Fie M.c.ntrziere ntrzierea de gard asociat unei condiii c n monitorul M. Se presupune disponibil un
ceas habs, care pune la dispoziie timpul absolut. Trebuie s adugm n programul primitivei c.semnalizare
instruciunea urmtoare:
hdeblocare[p]:=habs+M.c.ntrziere
unde hdeblocare[p] este un cmp nou al blocului de context al procesului p. Un proces, numit gardian,
deblocat la intervale regulate de timp parcurge mulimea contextelor i efectueaz tratamentul specificat
proceselor pentru care hdeblocare[p]>habs.
87. Realizarea unui nucleu de sincronizare. Algoritmi de baz
Programul monitorului trebuie s asigure dou funcii:

excluderea mutual pentru procedurile monitorului,


blocarea i deblocarea asociate primitivelor ateptare i semnalizare.
Fiecrui monitor M i sunt asociate urmtoarele structuri de date:
un dispozitiv de excludere mutual M.disp (lact), care poate lua dou valori liber i ocupat, i un fir de
ateptare M.fir asociat acestui dispozitiv. Iniial M.disp=liber, M.fir=<vid>.
fiecrei condiii c de M i este asociat un fir M.c.fir, un contor de gard M.c.ntrziere i, pentru
condiiile asociate unei ntreruperi, un indicator boolean M.c.ntr_sosit.
Firul proceselor eligibile este determinat de f_eligibil.
Pentru un monitor M vom cerceta programul a patru secvene intrare, ieire, c.ateptare i c.semnalizare
(secvenele intrare i ieire sunt inserate de compilator i ncadreaz execuia procedurilor externe ale
monitorului). S definim mai nti procedurile de gestiune a dispozitivului:
cerere_disp(M, p):

eliberare_disp(M):

if M.disp=ocupat then

if vid(M.fir) then

intrare(p, M.fir);
stare[p]:=blocat
else

M.disp:=liber
else

ieire(q, M.fir);
M.disp := ocupat;

intrare(q, f_eligibil);

intrare(p, f_eligibil);

stare[q]:=eligibil

stare[p]:=eligibil

endif

endif
Cele patru secvene se vor scrie utiliznd urmtoarele proceduri:
intrare(M):
prolog;

ieire(M):
prolog;

p:=<proces apelant>;

p:=<proces apelant>;

cerere_disp(M, p);

eliberare_disp(M);

alocare_procesor;

intrare(p, f_eligibil);
alocare_procesor;

c.ateptare:

c.semnalizare:

prolog;

prolog;

p:=<proces apelant>;

p:=<proces apelant>;

intrare(p, M.c.fir);

if non_vid(M.c.fir) then

stare[p]:=blocat;

ieire(q, M.c.fir);

eliberare_disp(M);

cerere_disp(M, p);

alocare_procesor;

cerere_disp(M, q);
eliberare_disp(M)
else

intrare(p, f_eligibil)
endif
alocare_procesor;
S ne amintim, c secvena prolog asigur salvarea contextului i intrarea n seciunea critic, iar secvena
alocare_procesor asigur alocarea procesorului i prsirea seciunii critice (v.4.3.4).
Notm, c n primitiva semnalizare, procesul apelant p i procesul deblocat q sunt introduse (cu ajutorul
primitivei cerere_disp) n firul de ateptare pentru a intra n monitor. Procesul activat prin intermediul
primitivei este primul proces din acest fir. Nu am ncercat s reducem numrul transferurilor ntre fire
pentru a realiza o implementare optimal.
88. Realizarea unui nucleu de sincronizare. Tratarea ntreruperilor
Pentru asigurarea uniformitii mecanismelor de sincronizare fiecrei ntreruperi i se asociaz:
o condiie ntr-un monitor,
un proces ciclic care realizeaz tratarea ntreruperilor, n stare de repaus acest proces este n ateptarea
condiiei.
O condiie poate fi asociat unui singur nivel de ntrerupere. Sosirea unei ntreruperi provoac executarea
funciei semnalizare pentru condiia asociat. Prioritatea relativ a ntreruperilor este tradus n prioritatea
proceselor, care trateaz ntreruperile.
Mecanismul descris mai sus nu este absolut perfect. De exemplu, excluderea procedurilor monitorului nu
poate fi aplicat ntreruperilor. Se poate ntmpla ca o ntrerupere s fie cerut atunci cnd procesul, care
trateaz ntreruperile, este nc activ, din care cauz ntreruperea va fi pierdut. Evitarea acestui fenomen se
va face cu ajutorul unui indicator boolean, care memorizeaz sosirea unei ntreruperi. Vom avea:
<proces de prelucrare a ntreruperii>
ciclu
test

if nonM.c.ntr_sosit then
c.ateptare;

-- evitarea pierderii unei ntreruperi

go to test
endif;
<tratarea ntreruperii>
endciclu
<sosirea unei ntreruperi asociate lui M.c>
M.c.ntr_sosit := true;
c.semnalizare;

89. Realizarea unui nucleu de sincronizare. Tratarea erorilor

Principiul de tratare a erorilor const n blocarea procesului care a provocat eroarea i expedierea unui
mesaj procesului printe, care va putea lua msurile necesare (corectarea erorii i relansarea sau distrugerea
procesului, care a generat eroare). Pentru aceasta este folosit un fir special f_eroare (n conformitate cu
organizarea sistemului, poate fi prevzut un fir unic sau un fir pentru fiecare utilizator, pentru fiecare
subsistem, etc.).
Presupunem c o eroare care are loc n cursul execuiei unui proces provoac o deviere, tratarea creia se
va scrie astfel:
prolog;
p:=<proces apelant>;
intrare(p, f_eroare);
<tratare specific>;
stare[p]:=suspendat;
alocare_procesor;
Am definit o stare nou (suspendat), care se aplic unui proces activitatea cruia a fost ntrerupt de un
eveniment, considerat anormal (eroare de execuie sau aciunea primitivei suspendare, v.4.3.3).
Nu detaliem aici <tratare specific>, care trebuie s fie specificat de ctre procesul printe la momentul
crerii procesului descendent. Acest program conine, evident, codul de diagnosticare (identitatea
procesului generator de eroare, natura erorii), care trebuie transmis procesului printe ntr-un mod special,
conform gradului de urgen (actualizarea unui indicator, deblocare, etc.).
90. Operaii asupra proceselor. Crearea i distrugerea proceselor. Suspendarea i reluarea
Problema principal, condiionat de gestiunea dinamic a proceselor, este alocarea contextelor i numelor
proceselor. Pentru aceasta sunt utilizate dou metode principale:
pentru blocurile contextelor sunt rezervate un numr fix de amplasamente; amplasamentele neutilizate
sunt determinate de o valoare special (nil) a cmpului stare al lor; fiecare bloc este desemnat printr-un
numr, care este numrul utilizat pentru desemnarea procesului asociat;
amplasamentele rezervate blocurilor de context sunt alocate dinamic n memorie; numerele sunt alocate
proceselor de asemenea n mod dinamic i un tabel de coresponden, asociaz numrului fiecrui
proces adresa n memorie a blocului su de context.
n ambele cazuri vom presupune disponibil o procedur alocare_context(p), care realizeaz alocarea
contextului (blocul de context i spaiul de lucru) i ntoarce ca rezultat un numr p al procesului (nil, dac
crearea este imposibil, de exemplu, din cauza lipsei de spaiu suficient n memorie). Metodele de alocare a
spaiului de lucru nu sunt precizate aici. Numrul procesului creat este ntors drept rezultat al primitivei:
creare(p, context iniial):
prolog;
control;

-- verificarea drepturilor

alocare_context(p);
if p nil then
iniializare_context(i);
intrare(p, f_eligibil)

endif;
intrare(proces apelant, f_eligibil);
alocare_procesor;

-- este ntors p drept rezultat

Contextul iniial este specificat de ctre procesul creator: el trebuie s defineasc valoarea iniial a
registrelor i a cuvntului de stare a procesului creat, starea iniial a spaiului de lucru, atributele, cum ar fi
prioritatea i drepturile. Unele cmpuri ale cuvntului de stare sunt predefinite i nu pot fi modificate
(modul, mascarea ntreruperilor, etc.). Pentru elementele legate de protecie (drepturile de acces), procesul
creat nu poate avea drepturi superioare drepturilor procesului creator; n caz contrar atributele de protecie
sunt declarate defecte.
Distrugerea unui proces trebuie s implice eliberarea resurselor, care i fuseser alocate. Printre aceste
resurse, doar numele i contextul sunt gestionate direct de nucleu; celelalte resurse, cum ar fi fiierele, sunt
preluate de mecanisme specifice.
Distrugerea unui proces, care se afl n seciunea critic poate conduce la o blocare. Seciunile critice ale
monitoarelor sunt gestionate direct de nucleu. Este posibil s se asocieze unui proces numrul
dispozitivului de blocare, care se afl n posesia procesului dat (el poate fi angajat n mai multe apeluri
incorporate), i s difereniem distrugerea procesului pn cnd valoarea acestui numr nu va fi 0. O alt
soluie const n examinarea periodic a fiecrui dispozitiv de blocare i s eliberm dispozitivul de
blocare, dac procesul care l posed a fost distrus.
Principiul primitivei distrugere este dat n schema de mai jos:
distrugere (p):
prolog;
control;

-- verificarea drepturilor

eliberare_context(p);
intrare(proces apelant, f_eligibil);
alocare_procesor;
Procedura eliberare_context trebuie s asigure eliberarea resurselor ocupate de procesul distrus i de
descendenii acestuia:
eliberare_context(p):
list:=<lista firelor procesului p>;
restituire_bloc_context(p);
restituire_memorie(p);
for q list do
eliberare_context(q)
endfor;
Primitiva suspendare
Primitiva suspendare permite procesului-printe s controleze activitatea unui proces descendent,
ntrerupnd n mod forat execuia acestuia. O utilizare curent este suspendarea unui proces, angajat ntr-o
bucl infinit. Procesul ntrerupt n acest mod este transferat ntr-un fir de ateptare special, care poate fi
firul f_eroare, utilizat pentru devieri.

Efectul primitivei suspendare poate fi ca i al unei devieri i programul de tratare poate fi analogic.
Suspendarea unui proces pune o problem analogic celei de distrugere, dac procesul se afl n seciunea
critic ntr-un monitor.
suspendare(p):
prolog;
control;
< tratare seciune critic>;
f:=<fir care conine p>;
extragere(p, f);
intrare(p, f_eroare);
stare[p]:=suspendat;
intrare(proces apelant, f_eligibil);
alocare_procesor;
Primitiva reluare permite unui proces s deblocheze un fir suspendat, dup modificarea eventual a
contextului su.
reluare(p):
prolog;
control;
extragere(p, f_eroare);
stare[p]:=eligibil;
intrare(proces apelant, f_eligibil);
intrare(p, f_eligibil);
alocare_procesor;
91. Excluderea mutual i alocarea procesorului intrebarile de mai jos
92. Realizarea pentru cazul monoprocesor
n acest caz excluderea mutual este realizat prin mascarea ntreruperilor. Pentru aceasta trebuie pregtit
masca ntreruperii n cuvntul de stare, care ar specifica programele asociate primitivelor de tratare a
ntreruperilor. Dac notm prin proces_ales o variabil global, care conine numrul procesului ales, iar
prin salv_csp locaiunea n care a fost salvat cuvntul de stare a procesorului la apelarea supervizorului sau
la ntrerupere, prologul va fi de forma:
prolog:
<mascarea ntreruperilor> -- masca n cuvntul de stare
csp[proces_ales] := salv_csp;
salv_registre(Reg[proc_al]);

Programul dispecerului, care de asemenea realizeaz ieirea din seciunea critic, are grij s aloce
procesorul primului proces din firul de procese eligibile. Pentru simplificarea manipulrii acestui fir este
binevenit s fie introdus aici un proces special cu prioritate joas, care rmne tot timpul n coada firului i
nu poate fi blocat. Acest proces, care poate fi ales doar atunci cnd el este unicul eligibil, execut o
activitate de fond, care nu este urgent sau o simpl bucl de ateptare. El garanteaz, deci, c firul
proceselor eligibile nu este niciodat vid.
f_elig
ibil

Csp
Reg
Prio
p =6
1 c.fii

p
2

p
3

er

f_elig
ibil

c.fiie
r

p
5

Cuvnt de
stare
Registre

proc_
al

p
5

p
1

p
4

p
6

p
2

Csp
Reg
2

Procesor

p
4
(a) nceputul
executrii
c.ateptare
Cuvnt de
stare
Registre

proc_
al

Procesor

p
3

(b) sfritul
executrii
c.ateptare

1
p
6Fig.4.5. Alocarea
procesorului

Programul dispecerului este de forma:


alocare_procesor:
ieire(proces_ales, f_eligibil);

ncrcare_registre(Reg[proc_al]);
ncrcare_csp(csp[proces_ales]);
Figura 4.5 ilustreaz principiul de funcionare a nucleului, exemplificnd efectul global al unei realocri a
procesorului dup blocarea procesului ales.
93. Realizarea pentru cazul unui sistem multiprocesoral
Descrierea, care urmeaz este inspirat din [13]. Vom specifica mai nti organizarea fizic a sistemului.
Avem n procesoare identice, care acceseaz o memorie comun. Fiecare procesor, desemnat printr-un
numr (de la 0 la n-1), i cunoate numrul propriu. Regimului de funcionare multiprocesor i sunt
specifice dou instruciuni:
Test and Set(R, m)

asigur excluderea mutual (4.1.1.2)

ntrerupere(k) :

provoac o ntrerupere a procesorului k.

O ntrerupere sau un apel de supervizor provoac introducerea cuvntului de stare i a registrelor


procesorului n cauz ntr-o stiv n memorie, proprie acestui procesor.
Orice primitiv a nucleului poate fi executat de oricare din procesoare. Vom mpri ntreruperile n
ntreruperi, destinate unui procesor specific (ceasul procesorului, instrucia ntrerupere(k)) i ntreruperi
banalizate (intrri-ieiri, de exemplu), care sunt tratate de orice procesor. n acest caz pentru a fi retras se va
alege procesorul, care execut procesul cu cea mai mic prioritate. Numrul acestui proces se afl ntr-un
amplasament rezervat de memorie kmin i vom considera, c un dispozitiv fizic ndreapt ntreruperile
banalizate spre procesorul cu numrul kmin. Vom utiliza acelai principiu de alegere i n cazul unei alocri a
procesoarelor.
Pentru ca firul proceselor eligibile s nu fie vid vom aduga aici n procese de prioritate joas. Numrul
procesului ales pentru a fi executat de procesorul k vom nota proc_al[k].
Excluderea mutual a primitivelor nucleului utilizeaz un dispozitiv de blocare, consultat i actualizat cu
ajutorul instruciunii Test And Set.
prolog:

-- procesorul k

<mascare ntreruperi>;
Csp[proc_al[k]]:=top(stiv_csp);
Reg[proc_al[k]]:=top(stiv_reg);
test:

Test And Set(R, dispozitiv de blocare);


if R 0 then
go to test

-- ateptare activ

endif
Dispecerul va asigura ca cele n procese alese s fie la orice moment de timp cu prioritatea cea mai nalt
printre procesele eligibile. Deoarece executarea primitivei curente poate modifica firul proceselor eligibile,
prioritatea primului proces eligibil este comparat cu prioritatea procesului ales pentru procesorul kmin.
Dac aceasta este superioar procesorul dat este retras cu ajutorul instruciunii ntrerupere.
alocare_procesor:

-- pentru procesorul cu numrul k

ieire(proces_ales[k], f_eligibil);

pr1:=Prio[primul(f_eligibil)];
pr2:=Prio[proc_al[kmin]];
if Prio[proc_al[k]] < pr2 then

-- actualizarea lui kmin

kmin:=k
endif;
disp_de_blocare:=0; -- terminarea seciunii critice
if pr1 > pr2 then
ntrerupere(kmin)

-- retragere

endif;
ncrcare_registre(Reg[proc_al[k]];
ncrcare_csp(Csp[proc_al[k]];

-- demascarea ntreruperilor

Tratarea ntreruperii de retragere (instruciunea ntrerupere) a procesorului se reduce la realocarea


procesorului ntrerupt:
<tratarea ntreruperii de retragere a procesorului k>
prolog;
intrare(proc_al[k], f_eligibil);
alocare_procesor;

94. Procese i fire n Linux. Intrebarea de mai jos


95. Crearea i distrugerea proceselor. Demoni n Linux. Obinerea informaiilor despre procese
n Linux procesele se nmulesc prin clonare: apelul de sistem, care creaz un proces nou, se numete
clone, iar procesul fiu este o copie aproape exact a procesului printe, doar c mai departe va executa
codul su, iar procesul printe ceea ce este scris dup apelarea lui clone. Diferenele pot deveni foarte
mari i dac dorim s evitm diferenierea, apelarea lui clone permite s definim urmtorii indicatori
(flags), care vor specifica momentele comune ale fiului i printelui:

Spaiul de adrese (Clone_VM);

Informaiile despre sistemul de fiiere (Clone_FS);

Tabelul fiierelor deschise (Clone_FILES);

Tabelul programelor de tratare a semnalelor (Clone_SIGHAND);

Printele (Clone_PARENT) n acest caz, evident, va fi creat un proces frate.

Firele sunt realizate n biblioteca standard de susinere a programelor cu mai multe fire ca i procesele,
generate cu indicatorul Clone_VM, i, din punctul de vedere al nucleului sistemului, nu se deosebesc de
alte procese. ns n unele biblioteci de alternativ pot exista diferene.

Mai exist fire, numite handicapate, generate de funcia kernel_thread pentru necesiti interne ale
sistemului. Acestea nu au parametri pentru linia de comand, de obicei nu au fiiere deschise, etc. Deoarece
aceste fire (procese) de asemenea figureaz n lista lucrrilor, adesea n literatur poate fi ntlnit noiunea
de proces propriu-zis, creat din spaiul utilizatorului (userspace), i noiunea de lucrare, prin aceasta
nelegndu-se toate procesele, inclusiv procesele interne ale nucleului.
Procesele sunt create prin utilizarea funciilor din familia exec ale bibliotecii Linux standard: execl,
execlp, execle, execv, execve, execvp. Dei formatul de apelare este diferit, n ultim instan execut
acelai lucru: nlocuiesc codul din procesul curent cu codul, care se afl n fiierul indicat. Fiierul poate fi
un fiier binar executabil Linux, un script al interpretorului limbajului de comand, un fiier binar de un alt
format (de exemplu, o clas java, un fiier executabil DOS). n ultimul caz modalitatea de prelucrare va fi
determinat de modulul de adaptare a nucleului binfmt_misc. Din aceast cauz, operaia de lansare a unui
program, care n DOS i Windows formeaz un tot ntreg, n Linux (i n Unix, n general) este mprit n
dou: mai nti are loc lansarea propriu-zis, iar apoi se va determina care program va fi executat. Are oare
aceasta sens i care sunt cheltuielile suplimentare? Doar crearea copiei unui proces presupune copierea
unui volum semnificativ de informaii!
n mod sigur putem afirma c are sens aceast abordare. Foarte frecvent un program trebuie s
ndeplineasc unele aciuni nainte de nceperea propriu-zis a execuiei lui. De exemplu, lansm dou
programe, care-i transmit reciproc date prin intermediul unui canal fr nume. Astfel de canale sunt create
prin apelarea de sistem pipe, care returneaz o pereche de descriptori de fiiere de care pot fi legate, de
exemplu, fluxul standard de intrare (stdin) al unui program i de ieire (stdout) al celuilalt program.
Aceasta este posibil deoarece mai nti sunt create procesele, apoi vor fi executate manipulrile necesare cu
descriptorii fiierelor i doar dup toate acestea este apelat funcia exec.
Aceleai rezultate pot fi obinute n Windows NT ntr-un singur pas, dar ntr-un mod mult mai complicat.
Ct despre cheltuielile suplimentare ele sunt n majoritatea cazurilor minime, deoarece dac este creat
copia unui proces datele proprii ale acestuia nu sunt fizic copiate. i aceasta din cauza c este utilizat
procedeul copy-on-write: paginile datelor ambelor procese sunt marcate ntr-un anumit mod i doar atunci
cnd un proces va ncerca s modifice coninutul uneia din paginile sale aceasta va fi duplicat.
Primul proces este lansat n sistem la iniializarea nucleului. Fragmentul de cod de mai jos este partea de
ncheiere a procedurii de iniializare a nucleului sistemului de operare Linux:
if (execute_command)
execve(execute_command,argv_init, envp_init);
execve("/sbin/init",argv_init,envp_init);
execve("/etc/init",argv_init,envp_init);
execve("/bin/init",argv_init,envp_init);
execve("/bin/sh",argv_init,envp_init);
panic("No init found. Try passing init= option to kernel.");}
Este fcut ncercarea de comutare a procesului la fiierul, indicat n linia de comand a nucleului, apoi la
fiierele
/sbin/init, /etc/init, /bin/init i, n sfrit, la fiierele din /bin/sh.
Distrugerea proceselor
La terminarea execuieia unui proces (normal, forat sau accidental), el este distrus elibernd toate
resursele, care fusese alocate anterior. Dac procesul printe se termin naintea procesului descendent,
ultimul devine orfan (orphaned process). Toi orfanii sunt nfiai n mod automat de programul init,
executat de procesul cu numrul 1, care duce evidena terminrii execuiei lor.

Dac a fost terminat deja execuia procesului descendent, iar procesul printe nu este gata s recepioneze
de la sistem semnalul despre acest eveniment, descendentul nu dispare total, ci este transformat n Zombie;
n cmpul Stat aceste procese sunt notate cu litera Z. Procesele Zombi nu cer timp de procesor, dar n
tabelul proceselor este pstrat linia lor i structurile respective ale nucleului nu sunt eliberate. Dup
terminarea execuiei procesului printe, procesul Zombi orfan devine pentru o perioad scurt de timp
descendentul lui init, ca mai apoi s moar definitiv.
Un process poate s cad n hibernare, fr a putea fi scos din aceast stare: n cmpul Stat acest
eveniment se va nota prin litera D. Procesele aflate n hibernare nu reacioneaz la cererile de sistem i pot
fi distruse doar prin rencrcarea sistemului.
Demoni n Linux
Demon (daemon) n Linux este numit procesul predestinat s lucreze n regim de fond fr terminal i
care execut anumite operaii pentru alte procese (nu obligator pe calculatorul Dumneavoastr). De obicei,
demonii i ndeplinesc n linite lucrul i ne amintim de ei doar n cazul unor situaii ieite din comun:
spaiu insuficient demonul singur informnd utilizatorul despre aceasta, sau refuz s lucreze i suntei
ntrebat de ef cnd se vor termina problemele cu imprimant .
Pentru multe calculatoare demonii, care servesc procesele altor calculatoare, sunt rar utilizai din care cauz
nu trebuiesc pstrai constant n memorie cu cheltuieli neraionale ale resurselor sistemului. Pentru
coordonarea lucrului acestora a fost creat un superdemon inetd (Internet daemon).
n fiierul de configurare inetd (/etc/inetd.conf) este indicat care demon acceseaz un serviciu anume de
Internet. De obicei, cu ajutorul lui inetd sunt apelate programele pop3d, imap4d, ftpd, telnetd (exerciiu determinai serviciul pus la dispoziie), etc. Aceste programe nu sunt n mod constant active, n rezultat, ele
nu pot fi considerate demoni n adevratul sens al cuvntului, dar, deoarece ele sunt create de un demon
adevrat, sunt numite demoni.
Pentru obinerea informaiilor despre procese, vizualizate de programele ps i top, Linux-ul utilizeaz
un sistem special de fiiere, numit procfs. n majoritatea distributivelor el este iniializat la lansarea
sistemului de operare cu titlul de catalog /proc. Datele despre procesul cu numrul 1 (de obicei /sbin/init)
se afl n subcatalogul /proc/1, despre procesul cu numrul 182 - n /proc/182, etc. Toate fiierele,
deschise de un proces, sunt reprezentate sub forma unor referine simbolice n catalogul /proc/<pid>/fd, iar
referina la catalogul rdcin este pstrat ca /proc/<pid>/root.
Sistemului de gestiune a fiierelor procfs i sunt asociate i alte funcii. De exemplu, cu ajutorul comenzii
echo 100000>/proc/sys/fs/file-max un superuser poate indica, c se permite deschiderea unui numr de
pn la 100000 de fiiere, iar comanda echo 0>/proc/sys/kernel/cap-bound va retrage proceselor din
sistem toate drepturile suplimentare, adic va priva sistemul de noiunea superuser.
Informaii utile pune la dispoziie programul lsof. Acesta returneaz lista tuturor fiierelor, utilizate la
momentul curent de ctre procese, inclusiv cataloagele folosite de ctre unele procese n calitate de catalog
curent sau catalog rdcin, bibliotecile dinamice, ncrcate n memorie, etc.