Documente Academic
Documente Profesional
Documente Cultură
Victor Beşliu
Ciclu de prelegeri pentru studenţii programelor TI, SI, IS
01.09.2020
1 12:47:14
Literatura (principală)
В.Е.Карпов, К.А.Коньков
Основы операционных систем
Literatura (suplimentară)
Эндрю Таннебаум
Современные операционные
системы, 2-е издание
Literatura (suplimentară)
Вильям Столлингс
Операционные системы
4-е издание
1. INTRODUCERE
1.1. NOŢIUNI DE BAZĂ ŞI CLASIFICĂRI
1.2. SISTEMUL DE OPERARE ŞI PROCESELE
1.3. MAŞINĂ IERARHICĂ ŞI MAŞINĂ EXTINSĂ
1.4. ALTE PUNCTE DE VEDERE ASUPRA SISTEMELOR DE OPERARE
1.5. EVOLUŢIA SISTEMELOR DE OPERARE
1.6. EXEMPLE DE SO: MS DOS, WINDOWS, UNIX ŞI ALTE SISTEME
Scopul lucrării: expunerea bazelor contemporane ale metodelor şi mijloacelor de
elaborare a resurselor program de sistem (inclusiv operaţii asincrone, tratarea
întreruperilor, compromisele dintre dispozitivele tehnice şi resursele program,
interfeţele sistemelor de operare) şi pregătirea cititorului pentru analiza şi
proiectarea sistemelor de operare (SO).
01.09.20
20 6
12:47:14
Structura sistemului de calcul
și locul disciplinei în ciclul general al cursurilor
de tehnologia informației
Programe
aplicative
Alte programe
Programe de sistem
de sistem
Sisteme de operare: Meanisme
Sistemul de operare interne și principii de proiectare
Resurse Arhitectura calculatorului
tehnice și limbajul de asamblare
Prin noţiunea de sistem de operare înţelegem modulele program ale unui SC, care
administrează resursele tehnice. Modulele în cauză soluționează situațiile de conflict,
optimizează productivitatea sistemului, sporesc eficiența utilizării lui. Ele joacă rol de
intermediar (interfață) între programele utilizatorului și componentele tehnice ale
calculatorului. Alte denumiri istorice ale SO: program de administrare, monitor, supervizor.
01.09.20
20 8
Fig.1.1. Relaţia dintre un sistem de operare şi componentele
12:47:14 unui calculator.
Fig. 1.2. Sistemul de operare-interfaţă între hardware şi utilizator
01.09.20
20 9
12:47:14
Software de sistem Aplicaţii
01.09.20
20 11
12:47:14
Scurt istoric din dezvoltarea
sistemelor de calcul
Prima generație (1945 – 1955)
Calculatoare pe tranzistori
Începe separarea personalului
Dezvoltarea rapidă a limbajelor de programare
Introducerea sarcinilor folosind cartelele perforate
Depanarea programului folosind listingul
Pachete de sarcini și sistemele de tratare pe loturi
01.09.20
20 15
12:47:14
Istorie
UNIX
• o versiune mult redusă a MULTICS
• implementat de Ken Thompson
• portabil (scris în C)
• System V, BSD
01.09.2020 12:47:14 19
Scurt istoric din dezvoltarea
sistemelor de calcul
Generația a patra (1980 – ???)
Managerul SO
rețelei
Aplicația 1
Micronucleu
Managerul
memoriei
Regim privilegiat
Aplicația 2 Managerul
fișierelor
Structura internă
a sistemelor de operare
Arhitectura micronucleu (microkernel)
Mașini virtuale
SO pune la dispoziția fiecărui utilizator o copie a resurselor tehnice virtuale
proprii (virtual hardware)
Hardware real
Ce înțelegem prin Sistem de Operare?
Gestionarul resurselor
Protectorul utilizatorilor și programelor
Mașină virtuală
Кот в мешке
Nucleu care funcționează fără întrerupere
01.09.20
20 32
12:47:14
Magistrale
01.09.20
20 34
12:47:14
Magistrale
Linii de
• adresă (determină spațiul de adresă)
• date (împreună cu frecvența magistralei
determină lățimea de bandă)
• Control
Lățimea de bandă
• numărul de linii de date x frecvența magistralei
35
01.09.2020 12:47:14
Concepte hardware de bază
• SO interacționează cu hardware-ul la un nivel destul de scăzut
• sunt necesare cunoștințe despre hardware pentru a înțelege modul de
funcționare a sistemului de operare
01.09.20
20 36
12:47:14
Procesoarele
Arhitecturi
• bandă asamblare (a)
• superscalar (b)
• VLIW/EPIC
• RISC
• CISC
01.09.2020 12:47:14 37
Memoria
01.09.2020 12:47:14 38
Dispozitive de intrare/ieșire
în general sunt compuse din două părți
• un controller
• dispozitivul efectiv
39
01.09.2020 12:47:14
Concepte de bază
procese, fire de execuție
deadlock
memorie virtuală
sisteme de fișiere
interpretorul de comenzi
nucleul sistemului de operare
kernel mode vs user mode
kernel space vs user space
apeluri de sistem
40
01.09.2020 12:47:14
Procese
un program în execuție
are asociate mai multe resurse:
• un spațiu de adrese
• fișierele deschise
• alte resurse (memorie partajată, socketi, etc)
în general procesele sunt ierarhizate după relația
părinte-copil
SO oferă protecție dar şi comunicație interprocese
41
01.09.2020 12:47:14
Fire de execuție
un proces poate avea mai multe fire de execuție
firele de execuție dintr-un proces partajează resursele
acestuia (memorie, fișiere deschise etc.)
fiecare fir de execuție are un context
• context = informații despre starea thread-ului (stivă,
registre generale, registre speciale)
avantaje / dezavantaje
• paralelism cu o comunicație extrem de facilă și rapidă
• se pierde mai puțin timp pentru o schimbare de context
• nu există protecție între firele de execuție
42
01.09.2020 12:47:14
Blocare reciprocă (impas, deadlock
43
01.09.2020 12:47:14
Memorie virtuală
Adrese
• virtuale
• Fizice
MMU și SO fac
translatarea din
adrese virtuale
în adrese fizice
44
01.09.2020 12:47:14
Fișiere
cale, director rădăcină, director de lucru
descriptor de fișier / handle
fișiere speciale
• bloc
• caracter
• pipe-uri
• link-uri
01.09.20
20 46
12:47:14
Nucleul sistemului de operare
Nucleul SO are acces direct la hardware
Părți din nucleu sunt permanent rezidente în memorie
Imaginea nucleului
• Linux: /vmlinuz, /boot/vmlinuz
• Windows: %SystemRoot%\system32\ntoskrnl.exe
• Mac OS X: Mach 3.0 + *BSD
module / drivere
01.09.2020 12:47:14 47
Nucleul space vs user space
Nucleul rulează în mod privilegiat
• kernel mode
• kernel space
01.09.2020 12:47:14 48
Apeluri de sistem
Accesul la resursele sistemului se face prin apelarea
serviciilor puse la dispoziție de nucleu
01.09.2020 12:47:14 49
Componente ale SO
• gestiunea proceselor
• gestiunea memoriei
• gestiunea fișierelor
• gestiunea operațiilor de I/E
• gestiunea rețelei
01.09.2020 12:47:14 50
Gestiunea proceselor
• crearea și terminarea proceselor
• suspendarea și repornirea proceselor
• planificatorul de procese (scheduler)
• mecanisme de sincronizare
• mecanisme pentru comunicație inter-procese
• detectare/rezolvare deadlock-uri
• protecție
01.09.2020 12:47:14 51
Gestiunea memoriei
• gestiunea memoriei fizice și virtuale
• memorie virtuală, segmentare, paginare
• swaping
• gestiunea memoriei folosite de nucleu
• memorie rezidentă permanentă
• memorie rezidentă temporară
• gestiunea spațiilor de adrese
• malloc/free, mmap
• Protecție
01.09.2020 12:47:14 52
Gestiunea fișierelor
• translatarea operațiilor de acces asupra fișierelor
(open, close, read, write, seek) în operații de citire și
scriere pe disc
• caching și read-ahead
• compresie și criptare
• Protecție
01.09.2020 12:47:14 53
Gestiunea operațiilor de I/E
• interfață comună pentru drivere
• caching, buffering
• întreruperi, DMA
• I/O scheduling
01.09.2020 12:47:14 54
Gestiunea rețelei
01.09.2020 12:47:14 55
Noţiuni şi termeni din domeniul SO
SO - ansamblu de programe de control şi de serviciu care
ghidează un calculator în execuţia sarcinilor sale, asistă
programele de aplicaţie şi interacţionează cu utilizatorul prin
intermediul anumitor funcţiuni.
Natura funcţiilor şi modul în care acestea sunt realizate
determină atributele care caracterizează un sistem de operare:
• timpul de răspuns,
• simultaneitatea utilizării,
• eficienţa,
• partajarea resurselor şi protecţia informaţiei în calculator,
generalitatea,
• flexibilitatea,
• extensibilitatea,
• fiabilitatea şi disponibilitatea, 01.09.20
• transparenţa şi vizibilitatea. 20
12:47:14
56
Atribute
Timpul de răspuns exprimă durata intervalului delimitat de lansarea unei
cereri de serviciu şi achitarea acesteia de către sistem. Are două
componente: timpul de aşteptare pentru ca cererea respectivă să fie luată
în consideraţie şi timpul de execuţie a acestei cereri.
Simultaneitatea utilizării măsoară gradul în care un sistem poate să execute
în acelaşi timp mai multe lucrări.
Eficienţa măsoară proprietatea unui sistem de a folosi în mod optim
resursele de care dispune.
Partajarea resurselor şi protecţia informaţiei caracterizează nivelul la care
utilizatorii au posibilitatea să utilizeze în comun informaţia prezentă în
sistem şi nivelul la care pot să comunice între ei, în deplină siguranţă.
01.09.20
20 57
12:47:14
Atribute
Generalitatea, flexibilitatea şi extensibilitatea măsoară gradul în care un sistem
poate fi folositor şi adaptabil unui context specific, precum şi gradul în care se pot
include în sistem noi componente hardware şi software fără eforturi de proiectare
şi programare suplimentare.
Fiabilitatea şi disponibilitatea exprimă proprietatea unui sistem de a cădea foarte
rar în pană şi de a evita goluri în funcţionare din cauza defectării uneia sau mai
multor componente ale sale.
Transparenţa şi vizibilitatea exprimă pe de o parte proprietatea unui sistem de a
face invizibil utilizatorului ceea ce se află sub interfaţa care i se oferă şi, pe de altă
parte, capacitatea de a permite utilizatorilor săi să obţină anumite informaţii
despre modul cum el funcţionează.
01.09.20
20 58
12:47:14
Alte noțiuni
Resursele program (logice) reprezintă seturi de programe şi date
utilizate pentru soluţionarea anumitor probleme.
Programul este transcrierea într-un limbaj de programare a unui
algoritm, altfel – programul este o secvenţă de instrucţiuni sau
simplu, cod.
Utilizatorul (Userul) este oricare doritor să îndeplinească anumite
lucrări la calculator.
Lucrare - set de acţiuni, necesare pentru îndeplinirea unui lucru
anume. Sarcina poate conţine mai mulţi paşi. Paşi de task sunt
unităţi de lucru, care vor fi îndeplinite consecutiv, de exemplu, trei
paşi – compilare, încărcare şi execuţie.
Proces primind o lucrare de la utilizator, SO poate crea câteva
procese: secvenţe de calcul care pot fi efectuate paralel cu alte
secvenţe de calcul. Procesul se află în spațiul01.09.20
de20 adrese.
59
12:47:14
Tipuri de sisteme de operare
Valorile concrete ale atributelor sistemelor de operare şi combinaţii ale
acestora determină diverse tipuri de SO:
• secvenţiale,
• cu multiprogramare,
• cu prelucrare multiplă,
• în timp real, etc.
Un sistem secvenţial (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 execuţia unui alt program.
Sistemele cu multiprogramare acceptă la un moment dat mai multe programe
în memoria centrală, acestea aflându-se în diferite stadii de execuţie.
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 funcţionează î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. 01.09.2020 12:47:14
60
Clasificare SO
• SO pentru servere
• SO pentru sisteme multiprocesor
• SO pentru calculatoare personale
• SO pentru sisteme embedded
• RTOS
01.09.20
20 61
12:47:14
Obiective:
• maximizarea eficienţei sistemului de calcul şi a satisfacţiei utilizatorilor,
• minimizarea probabilităţii apariţiei unor erori
• maximizarea transparenţei sistemului de operare,
• garantarea securităţii datelor,
• optimizarea controlului comunicaţiilor în cazul unei reţele de calculatoare,
• minimizarea efortului concepţie - realizare.
Obiectivele - consecinţă ale dezideratului principal - un SO este destinat să
administreze resursele fizice şi logice ale sistemului de calcul
• memoria,
• procesorul (procesoarele),
• dispozitivele periferice
• informaţia.
Un sistem de operare este obligat:
• să păstreze informaţia despre starea fiecărei resurse,
• să ia decizia cărui proces să i se aloce resursa, în ce cantitate, când, cum şi unde,
• să aloce resursa şi, la momentul oportun, să o retragă.
01.09.2020 12:47:14 62
1.1.4. Exemple de sisteme de operare
Cea mai simplă configuraţie a unui calculator personal (PC) include o unitate centrală, o
memorie principală, un display, o tastatură şi un mouse. Această configuraţie, de
regulă, este completată de o memorie secundară şi o imprimantă.
Utilizatorul unui astfel de sistem va cere minimum următoarele două tipuri de servicii:
• identificarea şi crearea unor fişiere sau mulţimi structurate de informaţii;
stocarea acestor fişiere în memoria secundară; transferarea informaţiilor între
fişiere şi dispozitivele de intrare/ieşire;
• execuţia unor programe existente sau introduse sub formă de fişiere în PC;
introducerea datelor necesare pentru execuţia programului (de la tastatură, dintr-
un fişier sau de la alte surse periferice); listarea rezultatelor la display, imprimantă
sau copierea lor într-un fişier.
Sistemul de operare va acorda aceste servicii prin intermediul unui limbaj special,
numit limbaj de comandă, introducându-se de la tastatură instrucţiuni de forma
<acţiune> <parametri> sau utilizând mouse-ul şi o interfaţă grafică a utilizatorului,
acţionările mouse-lui fiind imediat interpretate de sistem.
01.09.2020 12:47:14
63
Exemple de secvenţe tipice de activităţi în cazul unui PC:
Reactor
Robinete
A Captoare
C
Semnale de
măsură
Înregistrări
Semnale de comandă
Calculator
Securitatea sistemului are prioritate maximă. Depăşirea unor valori critice trebuie să fie
detectată în orice moment şi tratarea acestor accidente va întrerupe toate operaţiile în
curs de execuţie.
Pentru o lungă perioadă de timp sistemele de operare de timp real au fost utilizate, de
regulă, în aplicaţii specializate cu constrângeri din punctul de vedere al vitezei de
răspuns şi al predictibilităţii. Dezvoltarea excepţională a reţelelor de calculatoare, a
Internetului şi necesitatea tot mai stringentă de asistare a aplicaţiilor în timp real (în
special multimedia) pe calculatoare de tip desktop au impus apariţia sistemelor de
operare de timp real.
Proiectarea sistemelor de operare de timp real este mult mai complicată decât
proiectarea sistemelor de operare clasice datorită numeroaselor condiţionări ce trebuie
rezolvate în timpul execuţiei (engl., runtime) şi care impun schimbarea în mod dinamic
a comportării unui element de execuţie (proces, task, thread).
Prin definiţie, toate aplicaţiile de tip Internet includ aspecte de timp real. Menţionăm
câteva dintre sistemele de operare de timp real comerciale mai cunoscute: QNX,
VxWorks, pSOS, Vrtx, OS/9, Lynx. Majoritatea acestor sisteme de operare sunt
portabile, fiind implementate pe numeroase procesoare.
O definiţie simplistă a software-ului de timp real ar fi: este acel software care trebuie să
opereze în cadrul unor constrângeri specifice de timp.
01.09.20
20 67
12:47:14
1.1.4.4. Sisteme tranzacţionale
Caracteristicile principale:
• sistemul gestionează un set de informaţii sau baze de date, care pot atinge volume
importante de informaţie;
• asupra acestor informaţii pot fi executate un anumit număr de operaţii predefinite
sau tranzacţii, adesea interactive;
• sistemul este dotat cu un mare număr de puncte de acces şi un mare număr de
tranzacţii se pot derula simultan.
Destinaţia principală a unor astfel de sisteme este furnizarea serviciilor necesare unei
mulţimi de utilizatori, fiecare dintre ei beneficiind de servicii:
• echivalente serviciilor unui calculator individual;
• legate de existenţa unei comunităţi de utilizatori: partajarea informaţiilor,
comunicaţii între utilizatori.
Caracteristicile obligatorii ale unui astfel de sistem îmbină, în egală măsură, calităţile
unui sistem de operare al unui calculator individual şi al unui sistem tranzacţional, cum
ar fi: disponibilitatea, fiabilitatea, securitatea, exploatarea optimă a caracteristicilor
resurselor fizice, calitatea interfeţei şi serviciilor utilizatorului, facilitatea adaptării şi
extensibilităţii.
01.09.20
20 69
12:47:14
1.2. Sistemul de operare şi procesele
Noţiunea de proces este asociată conceptului de lucrare şi poate fi definită ca o suită
temporală de execuţii de instrucţiuni, considerată ca fiind o entitate de bază în
descrierea sau analiza funcţionării unui sistem. Evoluţia în timp a unui proces
presupune un consum de resurse, dictat de natura şi complexitatea instrucţiunilor de
execuţie. Orice utilizare a unei resurse este asociată, la un moment dat, unui proces şi
procesul respectiv îşi asumă răspunderea de utilizare a acestei resurse. În particular,
rezultă că ori de câte 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.
Procesul 1
Procesul 2
Procesul 3
Sistemul de
operare
Procesului i s-a
alocat
procesorul Procesul
aşteaptă
Ales (Exe) terminarea
operaţiei I/O
Operaţia de
I/O s-a
terminat
Eligibil Blocat
(Ready) (Wait)
Procesul 1 Procesul 2
Maşina extinsă
Sistemul de operare
Procesul 4
Procesul 3
Procesul 1 Procesul 2
Maşina extinsă externă
Maşina extinsă
internă
Maşina Programele
“goală” utilizatorului
(procese)
01.09.20
20 74
12:47:14
Taskuri
Planificator de taskuri
Procesul 2
Procesul 1 Procesul 3 Procese I/O care
I/O de sistem deservesc procesul 3
al utilizatorului
Proces creat Stratul 2
de utilizator
Proces I/O
Nivelul 5
Stratul 1
Nivelul 4
Nivelul 3
Nivelul 2 Stratul 0
Nivelul 1
Maşina
“goală”
Administrare
procesoare (P,V),
planificare procese
Administrare memorie
Administrare procesoare (nivel superior,
mesaje, creare şi distrugere procese)
Administrare dispozitive
01.09.20
Administrare informaţie 20 75
12:47:14
01.09.2020 12:47:14
77
Exemplul 2.1. O procedură p (apelantă) provoacă execuţia unei proceduri q
(apelate) cu ajutorul unei secvenţe de apel care conţine următoarele etape:
1. Pregătirea parametrilor, transmişi de către procedura p procedurii q,
2. Salvarea parţială a contextului lui p, necesar la retur,
3. Înlocuirea contextului procedurii p prin contextul lui q.
La revenire din q avem o schemă simetrică, doar contextul lui q fiind pierdut:
1. Pregătirea rezultatelor, transmise de către procedura q procedurii p,
2. Restabilirea contextului procedurii p, salvat înainte de apel.◄
01.09.2020 12:47:14 78
Structura de date - stiva de execuţie. Respectare ipoteze:
1. Parametrii unei proceduri sunt transmişi prin valori; la retur un singur rezultat este returnat,
2. Procedurile pot fi apelate recursiv (direct sau indirect).
Masca întreruperilor.
01.09.20
20 81
12:47:14
Întreruperi, excepții, apelarea supervizorului
Activităţi asincrone
Modelul descris mai sus poate fi folosit doar pentru un singur program, reprezentat printr-o
secvenţă de activităţi, executate pe un singur procesor. Unicele mecanisme necesare pentru
organizarea comunicărilor între activităţi sunt operaţiile de apelare şi retur.
Pentru cazuri mai generale sunt necesare noțiuni suplimentare, cum ar fi conceptele de
asincronism sau de protecţie reciprocă între activităţi.
Asincronism - efectul care îl pot avea asupra unei activităţi anumite evenimente exterioare.
Protecţie reciprocă între activităţi - modificarea mai profundă a contextului, atunci când se
trece de la o activitate la alta, în comparaţie cu un simplu apel de procedură.
82
01.09.2020 12:47:14
CDC Cyber 170: un PC şi 10 PP. Programele sistemului de operare erau executate pe
PP: unul dintre acestea, numit PS, are "grijă" de înlănţuirea lucrărilor şi alocarea
resurselor, celelalte, notate PES(i), erau specializate în operaţii de I/E. PC şi PP
comunicau prin intermediul unei memorii comune:
83
01.09.2020 12:47:14
Mecanisme de comutare a contextului
Comutarea contextului poate fi necesară din mai multe cauze distincte. Presupunem că
fiecărei cauze i-a fost asociat un număr de ordine. Pot fi întâlnite două scheme de
comutare a contextului.
1. Salvare în amplasamente fixe. Fiecărei cauze (numărul unei cauze fiind i) îi sunt ataşate în
mod constant două amplasamente de memorie adresele cărora le vom nota prin
csp_vechi[i] şi csp_nou[i] (csp semnificând cuvânt de stare program). Comutarea se
produce după cum urmează:
Mp[csp_vechi[i]]:=<cuvânt de stare program>
<cuvânt de stare program>:= Mp[csp_nou[i]]
În setul de instrucţiuni există o instrucţiune privilegiată schimbă_csp(adr) cu următorul efect:
<cuvânt de stare program>:= Mp[adr].
2. Salvare într-o stivă. Acelaşi procedeu în ceea ce constă cuvântul de stare nou. Însă
cuvântul de stare vechi nu este salvat într-un amplasament fix, ci într-o stivă specială:
ptr :=ptr+1
stiva[ptr] :=<cuvânt de stare program>
<cuvânt de stare program> := Mp[csp_nou[i]]
Instrucţiunea schimbă_csp(adr) este identică celei din 1); există însă şi o instrucţiune
restabileşte_csp, care restabileşte PSW folosind pentru acesta top-ul stivei:
<cuvânt de stare program> :=stiva[ptr]
ptr :=ptr-1 01.09.20
20 84
12:47:14
Comutarea contextului, descrisă mai sus, este declanşată sub influenţa stării unor
indicatori interni (din PSW) pe care procesorul îi consultă la interpretarea fiecărei
instrucţiuni. Conform semnificaţiei acestor indicatori şi maniera în care ei sunt
modificaţi, pot fi evidenţiate trei mecanisme de comutare, descrise în tabelul de mai
jos:
Tabelul 2.1. Mecanisme de comutare a contextului
Denumirea Cauza Utilizarea
mecanismului
Adesea toate aceste trei denumiri sunt înlocuite cu una singură - întrerupere.
01.09.2020 12:47:14 85
Întreruperi
Întreruperea - comutarea contextului procesorului declanşată de o cauză externă derulării
instrucţiunii curente. Fizic = trimiterea unui semnal procesorului, acest semnal provocând
schimbarea stării unuia dintre indicatorii, consultaţi în cursul executării fiecărei
instrucţiuni. 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 execuţia 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, diferenţa fiind legată de modul de tratare, protecţie,
informaţiile accesibile, etc.
Nivele de prioritate. Cauzele care duc la necesitatea întreruperii unui procesor sunt diferite,
drept rezultat şi programele predefinite, care tratează întreruperile diferă. Mecanismul
întreruperilor trebuie să poată deosebi aceste cauze. Două scheme de bază sunt utilizate în
acest scop:
1. Există un indicator unic pentru toate întreruperile. Acestui indicator îi este asociat un
program de tratare a întreruperilor. Codul întreruperii, care se conţine în PSW sau într-un
amplasament de memorie, dă posibilitatea deosebirii cauzelor. Programul de tratare a
întreruperilor consultă mai întâi codul întreruperii pentru a stabili originea acesteia, apoi se
va trece la tratarea propriu-zisă.
2. Fiecărei cauze este ataşat un indicator, se mai spune că fiecare cauză este ataşată unui nivel
de întrerupere. Fiecărui nivel îi corespunde un program distinct de tratare a întreruperii,
activat în mod automat de către mecanismul de comutare a contextului.
86
01.09.2020 12:47:14
Întreruperi
87
01.09.2020 12:47:14
Armare Dezarmat
Întrerupere Dezarmare
Declanşare
programată Armat
[ Punct de întrerupere ]
Aşteptare
Activ
Achitare
88
01.09.2020 12:47:14 Fig.2.3. Stările unui nivel de întrerupere
Priorităţi şi mascarea întreruperilor. Atunci când există mai multe nivele de întrerupere este
posibilă necesitatea modificării simultane a doi indicatori, legaţi de două cauze diferite. Conflictul
poate fi reglat stabilind o ordine de prioritate în cadrul nivelelor de întrerupere.
Declanşare programată. Pentru unele calculatoare există o instrucţiune de declanşare programată care
permite modificarea indicatorului, asociat unui nivel de întrerupere, din interiorul unui program.
Atunci când toate condiţiile necesare pentru ca o întrerupere să fie luată în consideraţie
sunt prezente, nivelul se numeşte activ. Această stare corespunde executării
programului de tratare a întreruperii.
Ieşirea din starea activă se face prin achitarea întreruperii. Achitarea este realizată
folosind instrucţiunea schimbă_csp, care termină tratarea schimbând contextul.
Operaţiile de armare-dezarmare, mascare-demascare şi declanşare a întreruperilor sunt
totdeauna realizate prin intermediul unor instrucţiuni privilegiate.
89
01.09.2020 12:47:14
Schema unui program de întrerupere.
O întrerupere forţează procesorul să reacţioneze la un eveniment. Executarea
programului curent este suspendată, comanda fiind transmisă programului de tratare a
întreruperii. Programul reluat de către procesor după tratarea întreruperii nu este în
mod obligator programul întrerupt (întreruperea putea avea drept scop realocarea
procesorului). Schema generală de tratare a unei întreruperi este prezentată în fig.2.4.
Programul întrerupt P
Tratarea întreruperii
Important! Natura unei devieri nu permite aplicarea noţiunii de mască. O deviere poate
fi suprimată, dar nici intr-un caz retardată.
01.09.20
20 91
12:47:14
Un apel al supervizorului (supervisor call, SVC, appel au superviseur, fr.) este o
instrucţiune chemată să provoace o comutare explicită a contextului procesorului.
Acest efect este analogic apelării unei proceduri, însă modificarea contextului este mai
profundă, fiindcă ea afectează întreg cuvântul de stare, nu numai contorul ordinal.
end
Măsurarea capacităţii memoriei. SO trebuie să se adapteze configuraţiei concrete, ca şi
condiţiilor particulare de utilizare (număr de utilizatori, priorităţi, etc.). Crearea unei
asemenea versiuni specifice se numeşte generarea sistemului de operare. Pentru a
reduce frecvenţa generărilor S.O. unii parametri de configurare pot fi determinaţi în
mod automat la iniţializare.
Astfel, poate fi determinată capacitatea memoriei operative utilizând o deviere pentru
adresa amplasamentului de memorie inexistent.
Realizarea prin program:
program principal:
begin
dev_nou:= <activ,master,mascat, adr măsurare>;
i:=1;
ciclu
<accesare cuvânt cu adresa i.p>;
i:=i+1;
endciclu;
ieşire ciclu: nbloc:=i;
dev_nou := <activ,master,mascat, adr tratare_deviere>;
end
procedura măsurare; -- apelare prin deviere
if cauză = adresă în afara memoriei then
csplucrare:= <activ,master,mascat, adr ieşire ciclu>;
încarcă_csp(csplucrare)
endif
01.09.20
La ieşirea din programul de măsurare a capacităţii memoriei
20 se va96restabili tratarea
normală a devierilor (procedura tratare_deviere). 12:47:14
Limitarea timpului de execuţie a unei proceduri. Realizarea prin program:
procedura iniţializare;
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);
restabileşte(zonă);
încarcă_csp(csplucrare);
…
retur: -- datorat terminării procedurii p
dezarmare(intr_ceas);
încarcă_csp(cspretur);
…
endcase
procedura intr_ceas; -- expirarea timpului limită
dezarmare(intr_ceas);
încarcă_csp(csperoare); 01.09.20
20 97
12:47:14
Culegerea unor date de măsurare. Perioada ceasului este de 5 μs. Datele trebuie culese
fiecare 100 ms. Deoarece timpul necesar culegerii datelor este cu mult inferior
perioadei de eşantionare, calculatorul poate executa alte lucrări în regim de fond.
Măsurare Măsurare Măsurare Măsurare
01.09.20
20 99
12:47:14
Programarea operaţiilor de intrare-ieşire
Intrare-ieşire numim orice transfer de informaţii din sau spre nucleul calculatorului.
Odată cu evoluţia calculatoarelor, în scopul unei mai bune utilizări a procesorului s-a ajuns la
necesitatea acordării unei autonomii organelor de intrare-ieşire încredinţându-le funcţii tot mai
complicate de înlănţuire şi comandă, procesorului central lăsându-i-se doar iniţiativa de lansare
şi de control a operaţiilor.
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. 01.09.20
20 100
12:47:14
Câteva scheme de organizare a perifericelor sunt prezentate în fig.2.5. Schema (c) este
proprie unui calculator de putere mare, (a) şi (b) corespund configuraţiilor
calculatoarelor de putere mai mică.
Magistrală Magistrală
UC UC
Cp Cp ADM
M M
p p Cp Cp
p p
(a) (b)
UC UC
Magistrală
C C
M
UC : unitate centrală
M : memorie
Cp Cp Cp
C : canal
ADM : acces direct la
01.09.20
memorie
(c) p p p p 20 101
Cp 12:47:14 : controler
p : dispozitiv periferic
Fig. 2.5. Organizarea intrărilor-ieşirilor
Un canal (sau unitate de schimb) este un procesor specializat în operaţiile de intrare-ieşire. El
poate fi lansat doar de un procesor central, nu posedă întreruperi, dar poate întrerupe un
procesor central. Setul de instrucţiuni ale canalului îi permite să acţioneze controlerele şi
perifericele, care-i sunt conectate. Mini- şi microcalculatoarele pot poseda organe, numite Unităţi
de acces direct la memorie (ADM), care sunt nişte canale simplificate.
Un periferic este un organ capabil să transfere informaţii din sau spre un suport extern. Controlerul
este legat de periferic printr-o interfaţă, care conţine un set de funcţii (intrare, ieşire,
semnalizări de comandă şi de accident) şi o linie de comunicaţie, care serveşte la transferul
informaţiilor.
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.
01.09.20
20 102
12:47:14
Diferite organe sunt desemnate, la fiecare nivel, printr-o adresă care permite să evidenţiem:
canale legate de memorie,
controlere ataşate fiecărui canal,
dispozitive periferice ataşate fiecărui controler.
Adresa este un simplu număr de ordine. Un periferic este desemnat printr-o adresă compusă din
<numărul canalului, numărul controlerului, numărul dispozitivului periferic>.
p
000
0
Controler
p
Canal 0 1 001
0 00
1 0 p 010
Controler
100
Canal 0 1
1 01, 10 p 011
101
110
1 0
Controler
p
111
Această organizare permite ameliorarea 1
11
performanţelor şi disponibilităţii sistemului.
Existenţa mai multor căi de acces la un
periferic diminuează riscul unor 01.09.20
Fig.2.6. Adresarea perifericelor
indisponibilităţi din cauza saturaţiei sau 20 103
12:47:14
ieşirii din funcţiune a unui canal sau
controler.
Metode de comandă a perifericelor
Programul, care controlează funcţionarea elementară a unui dispozitiv periferic se numeşte driver. Driverul
gestionează în mod direct controlerul perifericului, tratează întreruperile generate de acesta, detectează şi
tratează cazurile de eroare.
Vom prezenta mai jos modurile principale de control ale perifericelor şi primitivele elementare de intrare-ieşire.
Intrări-ieşiri sincrone
În acest caz nu există nici un fel de paralelism între procesare şi transferul informaţiilor. Procesorul este ocupat
pentru toată durata transferului.
Specificarea mecanismului
Operaţia de bază constă în transferarea unor informaţii elementare de volum fix între un amplasament de
memorie şi un dispozitiv periferic. Presupunem că volumul informaţiei transmise, care depinde de perifericul
considerat, este un octet. Starea ansamblului controler-periferic este definită printr-un cuvânt de stare, aflat în
controler. Acest cuvânt de stare conţine o mulţime de indicatori booleeni, dintre care 3 ne vor interesa aici:
preg : perifericul este pregătit (gata) de funcţionare,
term : transferul este terminat; perifericul poate să transfere un nou caracter,
err : în cursul transferului a avut loc o eroare.
Controlerul este comandat de UC cu ajutorul a 3 instrucţiuni de intrare-ieşire, efectul cărora este descris mai jos:
IN(adr_mem, adr_perif) : cerere de transfer tip intoducere a unui octet,
OUT(adr_mem, adr_perif) : cerere de transfer tip extragere a unui octet,
TEST(adr_perif) : copie cs într-un registru cu scopul de a consulta indicatorii.
Fie că vrem să extragem o secvenţă de n caractere care se află într-un masiv T[0..n-1].
Caracterul T[i], dacă i>0, poate fi extras doar dacă a fost transferat T[i-1]. Pentru a
verifica această condiţie se testează iterativ (aşteptare activă) indicatorul term.
iniţializare : term:=false;
TEST(adr_perif);
if nonpreg then
<tratare eroare>
endif;
for i:=0 to n-1 do
OUT(adr T[i],adr_perif);
ciclu: TEST(adr_perif);
if err then
<tratare eroare>
endif;
if nonterm then goto ciclu
endif;
endfor
Intrările-ieşirile sincrone sunt folosite la microprocesoarele cele mai simple sau atunci
când procesorul nu poate fi exploatat în mod util în timpul transferului.
105
01.09.2020 12:47:14
Intrări-ieşiri asincrone cu întreruperi
Specificarea mecanismului
Terminarea procesului de transferare a caracterului T[i] este semnalizată printr-o întrerupere.
Dacă acest caracter nu este ultimul (i<n-1), următorul caracter poate fi transmis. Procesul este
declanşat de transferul primului caracter. Acest transfer este cerut de către programul
principal prin intermediul unui apel a supervizorului (SVC intrare sau ieşire), care are drept
parametri: adresa perifericului, numărul de caractere care vor fi transferate, adresa de origine
sau de destinaţie a primului caracter, booleanul term, valoarea TRUE a căruia semnalizează
sfârşitul transferului.
Programul principal programul de tratare a întreruperii
term:=FALSE (la părăsirea lui T[i])
SVC i:=0;
ieşire OUT(adr T[i], adr_perif);
save context;
TEST(adr_perif);
… if err then
<tratare eroare>
else
if i<n-1 then
<tratare paralelă> i:=i+1;
OUT(adr T[i], adr_perif)
… else
term:=TRUE
if term then endif
… endif; 106
<restabilire context>
01.09.2020 12:47:14
Intrări-ieşiri buferizate în memorie
Diferenţa considerabilă dintre viteza de lucru a unităţii centrale şi cea a organelor periferice
impune "buferizarea" intrărilor-ieşirilor, adică introducerea unei zone-tampon de memorie
între periferic şi programul utilizatorului. Scopul este de a reduce timpul de inactivitate a
unităţii centrale, dezlegând funcţionarea acesteia de periferice.
Programul utilizatorului va transfera informaţiile din sau spre bufer, iar buferul va servi, în
mod paralel, drept sursă sau destinaţie la schimbul de date cu perifericul. Pentru a nu
supraîncărca memoria principală, buferul poate fi situat pe discul rigid.
Specificaţii:
• schimburile de informaţii cu perifericele se va face prin înregistrări de lungime fixă,
• zona-tampon este de volum fix egal cu N înregistrări,
• pentru un program utilizator, schimbul de informaţii cu zona-tampon trebuie să
simuleze schimbul cu perifericul - ordinea de depozitare sau de extragere a informaţiilor
trebuie să fie bine stabilită şi nici o înregistrare să nu fie pierdută,
• aşteptările inutile trebuie reduse la minimum,
• capacitatea suporturilor nu este limitată,
• transferul se va efectua fără eroare.
107
01.09.2020 12:47:14
Descrierea algoritmilor
Citire
Procedura citire(înreg) prezintă drept rezultat valoarea înregistrării citite. Realizată printr-o apelare a
supervizorului, are ca efect citirea din bufer a înregistrării următoare. Citirea este posibilă doar dacă
buferul conţine cel puţin o înregistrare, care nu a fost încă citită. În caz contrar, activitatea apelantă trece
în starea de aşteptare. În ambele cazuri, continuitatea alimentării buferului este asigurată de citirea unei
înregistrări de la perifericul de intrare, dacă un transfer nu are deja loc.
Terminarea transferului unei înregistrări în bufer provoacă o întrerupere. Pentru a menţine perifericul în
stare activă, programul de tratare asociat acestei întreruperi trebuie să relanseze transferul următor,
dacă mai există loc în bufer. Dacă activitatea apelantă era în aşteptarea sosirii unei înregistrări, ea
trebuie relansată. programul utilizator
periferic de
intrare citire (înreg)
Zonă-tampon cu N locaţiuni
procedura citire(înreg) tratare întrerupere
(apelare supervizor)
if buferul_nu este_vid then if buferul_nu este_plin then
extragere(înreg, tampon); lansare_transfer;
lansare_transfer în caz de necesitate; if aşteptare then // aşteptare pentru citire
else reluare citire
lansare_transfer în caz de necesitate; endif
108
aşteptare
01.09.2020 12:47:14
endif
Scriere
Schema care corespunde unei scrieri se obţine din precedenta, înlocuind după cum urmează:
citire prin scriere
extragere prin introducere
tampon_vid prin tampon_plin
tampon_plin prin tampon_vid
programul utilizator
periferic de
ieşire scriere (înreg)
Zonă-tampon cu N locaţiuni
Zonă-tampon
qcitire tcitire
110
01.09.2020 12:47:14
citire(înreg) tratare_întrerupere_perif_de_intrare
save(zonă_svc); save(zonă_întrerupere);
început: qcitire:=suc(qcitire);
if nvcitire<Ncitire then nvcitire:=nvcitire-1;
înreg:=bufer[tcitire]; if nvcitire>0 then
tcitire:=suc(tcitire); lansare_perif_de_intrare(qcitire)
nvcitire:=nvcitire+1; else
if citire_activ=false then citire_activ:=false
citire_activ:=true; endif;
lansare_perif_de_intrare(qcitire) if aşteptare_citire then
endif întrerupere_veche.act:=activ;
else aşteptare_citire:=false
if citire_activ=false then endif;
citire_activ:=true; restabilire(zonă_întrerupere);
lansare_perif_de_intrare(qcitire) încărcare_csp(întrerupere_veche);
endif; lansare_perif_de_intrare(qcitire)
elaborare prog.canal:
csplucrare:=<aşteptare,slave,demascat, adr început>; <sens=citire
aşteptare_citire:=true; adr.memorie=adr bufer[qcitire]
încărcare_csp(csplucrare); contor_octeţi=L>
endif; SIO
restabilire(zonă_svc); <prog=prog.canal
încărcare_csp(svc_vechi); perif= perif_de_intrare>
Situaţia dată este cunoscută sub numele de excludere mutuală şi este o consecinţă
112a execuţiei activităţilor
asincrone.
01.09.2020 12:47:14
3. Gestiunea activităţilor paralele
3.1. Exemple introductive
3.1.1. Administrarea tamponată a intrărilor-ieşirelor
3.1.2. Comanda unui proces industrial
3.2. Noţiune de proces secvenţial
3.2.1. Proces unic. Context
3.2.2. Relaţii între procese
3.3. Sincronizarea proceselor
3.4. Implementarea sincronizării
3.4.1. Probleme-tip
3.4.2. Administrarea unei resurse partajate
3.4.3. Comunicarea între procese
3.4.4. Administrarea intrărilor-ieşirilor
3.4.5. Sincronizare temporală
3.5. Gestiunea dinamică a proceselor
3.6. Sincronizarea în Windows
3.1.1. Administrarea tamponată a intrărilor-ieşirelor
scriere_linie
SL SD CD IF
tm1 tm2
(memorie) (memorie)
td
(disc)
Aceste patru activităţi sunt în mare măsură autonome - ele sunt executate pe
procesoare distincte, cu programe diferite.
Ele nu sunt totuși independente, deoarece accesează obiecte comune: două bufere în
memorie, tm1 şi tm2 şi unul pe disc, td.
114
01.09.2020 12:47:14
1) Condiţii, care stabilesc posibilitatea existenţei activităţilor
Execuția activităților modifică veridicitatea acestor condiții: astfel, imprimarea unei linii
pune în TRUE condiția “tm2 nu este plin”.
O activitate, care nu poate executa o acţiune, deoarece condiţia asociată are valoarea
FALSE, trebuie să aştepte până când valoarea logică a condiţiei devine TRUE.
SL SD CD IF
tm1 tm2
(memorie) (memorie)
td
115
01.09.2020 12:47:14
(disc)
2) Condiţii de validitate a informaţiilor partajate
Examinăm procesul de accesare a buferelor. Este posibilită accesarea simultană
de către două activităţi a unuia și același amplsament de memorie.
Exemplu: SD citeşte conţinutul unei înregistrări din tm1 pe care SL este în curs de
a o modifica. Rezultatul citirii riscă să fie incoerent, dacă nu vor fi luate măsuri
speciale de precauţie. Problema poate fi rezolvată impunând una din activităţi,
aflate în conflict, să “aştepte” până când cealaltă va termina accesarea.
Concluzii:
Lucrarea “imprimare buferizată” este realizată prin patru activităţi
simultane, în mare măsură autonome, care cooperează pentru atingerea scopului
final. Executarea corectă a lucrării impune restricţii logice în vederea derulării
acestor activităţi. Aceste restricţii pot conduce la întârzierea execuţiei unei
activităţi, care este obligată să aştepte producerea unui eveniment, provocat de o
altă activitate.
117
01.09.2020 12:47:14
Exemplul 2: rezumat
Continuarea acestui capitol are drept scop elaborarea unui suport formal
pentru aceste noţiuni, introducând conceptele de proces şi sincronizare şi
descriind modalităţile lor de utilizare în cadrul unui sistem informatic.
118
01.09.2020 12:47:14
Proces unic
Executarea unui program se traduce într-o suită de
acţiuni/activități
a1, a2,..., ai,...,
cu început(ai)<sfârşit(ai)
p q
(1)
p q p q p q
(2)
p q
(3)
Nivelul programelor. Să ne situăm mai întâi la nivelul de observare la care, prin convenţie,
executarea completă a fiecărui dintre programele P şi Q reprezintă o acţiune unică:
a) schema de tip 1 este a unei execuţii secvenţiale a lui p şi q. Ea este caracterizată de relaţiile:
sfârşit(q) < început(p) sau sfârşit(p) < început(q)
b) schemele de tip 2 sau 3 sunt scheme de execuţie paralelă. Ele sunt caracterizate de
sfârşit(p) > început(q) sau sfârşit(q) > început(p).
Nivelul de bază. La acest nivel este posibilă o distincţie între schemele 2 şi 3. Într-adevăr, în
schema 2, din considerente de existenţă a unui singur procesor, la un moment de timp dat
doar o singură activitate 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ă observaţii importante sunt necesare:
1) Diferenţa acestor scheme de execuţie este legată de alegerea nivelului de observare.
Astfel, la nivelul de bază, diferenţa dintre schemele 1 şi 2 dispare: ambele sunt
secvenţiale.
2) Alegerea nivelului de bază depinde de fineţea fenomenelor, care dorim să le
considerăm elementare. Dacă trebuie să studiem executarea instrucţiunilor în “pipe-
line” pe un procesor microprogramat, în calitate de nivel de bază va fi ales nivelul
microinstrucţiunilor, iar contextul va fi completat cu memoria microprogramelor şi
registrele interne.
Situaţia descrisă de schemele 1 şi 2 nu rezultă dintr-o legătură logică între p şi q, ci doar din
existenţa unui singur procesor. Ea poate fi generalizată astfel:
fie o mulţime de procese contextele cărora 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.
Funcţionarea corectă a unei mulţimi de procese, care participă la îndeplinirea unei lucrări
comune, implică relaţii logice de cooperare. Este comod să se separe această cooperare de
concurenţa pentru resursele fizice cu scopul de a simplifica înţelegerea şi aplicarea celor
două tipuri de relaţii. Pentru aceasta este folosită noţiunea de resurse virtuale:
fiecărei resurse fizice critice i se asociază tot atâtea copii imaginare (sau virtuale) ale acestei resurse
câte procese concurente solicită utilizarea ei. Trebuie să tratăm două probleme distincte:
1) respectarea relaţiilor de cooperare între procesele, care, fiecare posedă (conceptual)
resursele fizice solicitate şi pentru care paralelismul în execuţie nu este restricţionat de
competiţia pentru resurse,
2) reglarea problemei de concurenţă pentru resursele fizice printr-o serializare convenabilă a
01.09.20
execuţiei proceselor. Se va spune în acest caz, că realizăm 20 o alocare
124 a resurselor fizice.
12:47:14
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
menţionat, că această schemă logică reprezintă doar o notaţie compactă pentru mulţimea
schemelor reale posibile şi că ele sunt obligatoriu de forma 1 sau 2 din considerentele
unicităţii procesorului. Pentru o schemă reală şi una virtuală a unui proces dat este păstrată
doar ordinea de succesiune a evenimentelor (începutul şi sfârşitul activităţii) şi nu sunt
păstrate valorile absolute ale intervalelor de timp, care le separă.
Timpul folosit la reperarea evenimentelor în schema logică este numit timp logic.
a1 a2
+------+-----------------+------+ procesul p
b1 b2 (timp logic)
+--+-------+---------+ procesul q
a1 a2
+------+---+ +----------+ +----+------+ p (timp real, execuţia 1)
+--+--+ +-----+---------+ q
b1 b2
a1 a2
+---+ +---+-----------------+------+ p (timp real, execuţia 2)
+--+----+ +---+---------+ q
b1 b2
În toate cazurile a1 precede a2, b1 precede b2. 01.09.20
20 125
Fig.3.3. Timpul logic şi timpul12:47:14
real
Excluderea mutuală
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) :
procesul p: Ap : n=n+np procesul q: Aq : n=n+nq
Să realizăm decompoziţia acestor acţiuni în instrucţii, notând 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 acţiuni 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 actualizări a fost pierdută şi valoarea
finală a variabilei n este incorectă. Pentru evitarea acestei incoerenţe acţiunile Ap şi Aq
trebuie să fie executate în excludere reciprocă; se zice de asemenea că ele constituie
pentru p şi q secţiuni critice.
Este necesar să se respecte condiţia
sfârşit(Ap) < început(Aq) sau sfârşit(Aq) < început(Ap).
Această condiţie de serializare, care are efectul de a face Ap şi Aq să devină atomare,
este identică condiţiei deja întâlnite la accesarea unei resurse fizice critice. ◄
Excluderea mutuală constă în extinderea pentru secvenţa de acţiuni a proprietăţii de
indivizibilitate a acţiunilor nivelului de bază (acţiuni atomare). Posibilitatea executării
unor acţiuni atomare se află la baza mecanismelor care 01.09.20
realizează
20
sincronizarea.
126
12:47:14
Sincronizarea proceselor
Exprimarea şi implementarea restricţiilor de succesiune
Exemplul 3.4. Procesul p transmite informaţii procesului q scriind într-un segment a,
consultat de q (această transmitere are loc o singură dată). Este necesar să se
îndeplinească condiţia: sfârşit(scriere(a)) < început(citire(a))
Această relaţie exprimă restricţia, că citirea lui a de către q nu poate începe înainte de
terminarea scrierii lui a de către p. ◄
Exemplul 3.5. Rendez-vous. Fie N procese p1,..., pN. Definim în programul fiecărui 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 restricţiile de sincronizare se vor exprima după cum urmează:
pentru orice i, j din [1..N]: sfârşit(debut_i) < început(continuare_j) ◄
Restricţiile de sincronizare pot fi exprimate prin următoarele 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 condiţie de autorizare a depăşirii acestor puncte ale
traiectoriei lor temporale.
Punctele privilegiate astfel se vor numi puncte de sincronizare. 127
01.09.2020 12:47:14
Vom utiliza noţiunea de aşteptare pentru specificarea sincronizării proceselor. Această
specificare se va produce în două etape:
definirea punctelor de sincronizare pentru fiecare proces,
asocierea unei condiţii de depăşire fiecărui punct de sincronizare, condiţie exprimată
prin intermediul variabilelor de stare ale sistemului.
Vom ilustra acest mod de specificare pentru cele două exemple precedente. Notăm un
punct de sincronizare prin ps, iar condiţia de depăşire asociată prin aut(ps). Dacă această
condiţie are valoare TRUE, procesul în cauză este autorizat să execute instrucţiunea
etichetată cu ps.
Exemplul 3.6: var f : boolean init false
procesul p procesul q
scriere(a); <debut_q>;
f:=true;
<continuare_p> ps : citire(a)
aut(ps) : f:=true
A fost introdusă variabila de stare f pentru a exprima condiţia “procesul p a terminat
acţiunea 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 numărul procesului sosit în punctul de rendez-vous.◄
01.09.2020 12:47:14 128
Probleme de realizare a sincronizării
Vom încerca să implementăm sincronizarea specificată de condiţiile de depăşire. Pentru
aceasta trebuie să definim un mecanism de aşteptare şi să introducem noţiunea de
variabilă de blocare (mutex). O variabilă de blocare (e) este o
variabilă, care poate lua două valori: liber sau ocupat, valoarea iniţială este
ocupat. Asupra v.b. sunt posibile două operaţii, care sunt acţiuni indivizibile:
e:=<valoare> -- atribuirea imediată a unei valori
aşteptare(e).
Operaţia aşteptare(e), executată de un proces p, are următoarea specificaţie:
if e = ocupat then
starea(p) := blocat -- p este trecut în “aşteptarea lui e”
endif
Când e ia valoarea liber, toate procesele care aşteptau e trec în starea activ.
Vom încerca acum să realizăm cu ajutorul acestui mecanism sincronizarea pentru cele
două exemple.
Exemplul 3.8. var e : variabilă de blocare;
procesul p procesul q
scriere(a); <debut_q>;
e:=liber; aşteptare(e);
<continuare_p> citire(a) ◄
Analiza acestui sistem (care nu conţine alte variabile de stare, decât v.b. e) poate fi
făcută enumerând traiectoriile temporale posibile. Această analiză arată, că
sincronizarea este corectă atunci când operaţiile asupra v.b. sunt indivizibile.
01.09.2020 12:47:14 129
Exemplul 3.9. var e : v.b.;
n : integer init 0;
procesul pi
<debut i>;
A n:=n+1;
B if n<N then
aşteptare(e)
else
e:=liber
endif
<continuare i> ◄
O analiză mai atentă ne arată că acest program este incorect. Notând un registru local al
procesului i prin Ri, acţiunile (A) şi (B) pot fi descompuse după cum urmează:
load Ri, n
ai Ri, 1 -- adunare imediată
ci Ri, N -- comparare imediată
br () etichetă -- salt dacă Ri N
<aşteptare (e)>
...
etichetă : ...
Presupunem, că toate procesele sunt în aşteptarea punctelor lor de rendez-vous, cu excepţia
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.
01.09.2020 12:47:14 130
Monitorul – mecanism de sincronizare
Un monitor este constituit dintr-o mulţime de variabile de stare şi o mulţime 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
realizează blocarea sau deblocarea proceselor conform specificaţiilor problemei.
Condiţiile de blocare sau deblocare sunt exprimate ca funcţie ale variabilelor de
stare, iar mecanismul de execuţie a monitorului garantează manipularea acestor
variabile în regim de excludere mutuală.
Monitorul conţine un fragment de cod de iniţializare, executat o singură dată la
crearea monitorului.
01.09.20
20 131
12:47:14
Condiții de monitor
Blocarea şi deblocarea proceselor se exprimă, în procedurile monitorului, prin
intermediul unui tip de date numit condiţie.
O condiţie este declarată ca şi o variabilă, dar nu are “valoare”: o condiţie c poate fi
utilizată doar prin intermediul a trei operaţii sau primitive, efectul cărora este descris
mai jos (prin p am notat procesul, care le execută)
c.aşteptare : blochează procesul p şi îl plasează în “aşteptarea lui c”
c.vid : fn bool (true, dacă nu există nici un proces în aşteptarea lui c, altfel false)
c.semnalizare : if non c.vid then <deblocarea proceselor în aşteptarea lui c> endif
Procesele, care sunt în aşteptarea unei condiţii c, sunt grupate într-un fir de aşteptare
asociat lui c. Putem spune, că o condiţie furnizează proceselor un instrument de
desemnare a unui astfel fir de aşteptare.
Un proces deblocat de c.semnalizare îşi reia execuţia de la instrucţiunea, care
urmează imediat primitivei c.aşteptare, care-l blocase.
01.09.20
20 132
12:47:14
Exemplul 3.10. sinc: monitor;
var f: boolean;
term: condiţie;
procedura terminare_scriere;
begin
f:=true;
term.semnalizare
end
procedura debut_citire;
if f=false then
term.aşteptare
endif
begin -- iniţializare
f := false
end
end sinc
begin -- iniţializare
n:=0
end
end rendez_vous
01.09.20
20 135
12:47:14
Administrarea unei resurse partajate
Considerăm o resursă (fizică sau logică) partajată de o mulţime de procese. Utilizarea
acestei resurse trebuie să respecte nişte reguli de utilizare, destinaţia cărora constă în
garantarea unor proprietăţi specificate sau restricţii de integritate. Aceste restricţii sunt
specificate pentru fiecare resursă.
Cel mai simplu caz este acela al unei resurse pentru care singura restricţie de
integritate este de a fi utilizată în excludere reciprocă. Simpla grupare a procedurilor
sale de acces într-un monitor unic garantează respectarea acestor restricţii.
01.09.20
20 136
12:47:14
Alocarea resurselor banalizate
Considerăm o resursă pentru care există un număr fix de N exemplare. Un proces poate
accesa la cerere n unităţi din cele N, le poate utiliza şi apoi elibera. Toate unităţile sunt
echivalente din punctul de vedere al proceselor utilizatoare (banalizate).
Utilizarea resursei are loc conform schemei de mai jos.
ps:resurse.cerere(n); -- cerere pentru n unităţi
-- aşteptare în caz de eşec
<utilizarea unităţilor primite>
resurse.eliberare(n) -- eliberarea resurselor
Condiţia de sincronizare se va scrie pentru orice proces:
aut(ps) : n nlibere
Monitorul resurse va utiliza direct condiţia de sincronizare:
resurse: monitor;
var nlibere : integer;
disp : condiţie;
procedura cerere(n); procedura eliberare(n);
begin begin
while n>nlibere do nlibere:=nlibere+n;
disp.aşteptare; disp.semnalizare -- deblocare în lanţ
endwhile; end;
nlibere:=nlibere-n
end;
begin -- iniţializare
nlibere:=N 01.09.20
20
end 12:47:14
137
end resurse
resurse : monitor
type element : struct
lungime : integer
proc : proces
end;
var nlibere : integer;
disp : array[proces] of condiţie;
<declaraţia f.de aşt. 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 creştere a lungimii
disp[p].aşteptare
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 -- iniţializare
01.09.20
nlibere:=N; 20
f:=<vid>
138
12:47:14
end
end resurse
Modelul cititorului şi scriitorului
Să considerăm un fişier manipulat de procese din două clase diferite: cititori, care
consultă fişierul fără a modifica conţinutul lui şi scriitori, care pot modifica acest
conţinut. Fie pentru un moment arbitrar de timp ncit şi nscr numărul de cititori şi de
scriitori, respectiv, care folosesc o procedură de acces la fişier. Cererea de
asigurare a coerenţei fişierului ne impune să respectăm următoarele restricţii:
(nscr=0) şi (ncit0) -- fişier în citire
sau (nscr =1) şi (ncit=0) -- fişier în scriere
Fie fich un monitor care asigură respectarea acestor restricţii. Vom impune următoarea
formă a acceselor la fişier:
proces cititor proces scriitor
fich.debut_citire; fich.debut_scriere;
<acces citire> <acces scriere>
fich.terminare_citire; fich.terminare_scriere;
procedura debut_citire;
begin
nc:=nc+1;
if scr then procedura terminare_scriere;
c_cit.aşteptare; begin
endif scr:=false;
end if nc>0 then -- prioritate
cititorilor care aşteaptă
procedura terminare_citire;
c_cit.semnalizare
begin
nc:=nc-1; else
if nc=0 then -- ultimul cititor a terminat c_scr.semnalizare
c_scr.semnalizare endif
endif end
end
begin -- iniţializare
procedura debut_scriere;
begin scr:=false;
if scr or nc>0 then -- scriere sau citire în curs nc:=0
c_scr.aşteptare end
endif; end fich
scr:=true 01.09.20
20 140
end 12:47:14
Comunicarea între procese
Procesele pot comunica prin accesarea unei mulţimi de variabile comune. Acest mod de
comunicare este slab structurat şi ineficient - cere excluderea reciprocă a variabilelor.
Comunicarea prin mesaje - modelul producătorului şi consumatorului, realizată cu
ajutorul monitoarelor (3.4.3.1). O altă posibilitate, descrisă în 3.4.3.2, constă în a
considera operaţiile de comunicare ca un fel de mecanisme primitive de sincronizare. În
3.4.3.3 prezentăm o aplicaţie frecventă de comunicare – modelul client-server.
3.4.3.1. Modelul producătorului şi consumatorului
Un proces (producătorul) trimite mesaje unui alt proces (consumatorul), utilizând o zonă
tampon în memoria comună. Mesajele sunt de lungime fixă şi capacitatea tamponului
este de N mesaje.
Specificaţiile comunicaţiei:
• un mesaj dat poate fi preluat doar o singură dată după ce a fost depozitat în tampon,
• un mesaj nu poate fi pierdut;
• dacă tamponul conţine N mesaje nepreluate, nu pot fi depozitate alte mesaje,
• o operaţie “imposibilă” blochează procesul, care încearcă să o execute.
Condiţiile de depăşire (n numărul 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
Exemplul 3.13. Sistemul de operare Unix [9]. În sistemul Unix comunicarea între procese
utilizează zone-tampon, numite pipes (tuburi), administrate conform schemei producător-
consumator. Mesajele transmise sunt caractere. Un pipe (tub) leagă un emiţător şi un
receptor, conexiunea fiind stabilită dinamic. ◄
Exemplul 3.14. Limbajul Ada permite definirea proceselor. Forma sintactică a comunicărilor între
procese este apelarea procedurii, însă transmiterea parametrilor şi a rezultatelor are loc
conform principiului de transmitere a mesajelor cu rendez-vous. Recepţionarea
143 poate fi
condiţionată (un apel este acceptat doar dacă o condiţie specificată este satisfăcută). ◄
01.09.2020 12:47:14
3.4.3.3. Client-server
O aplicaţie curentă a comunicărilor între procese este relaţia client-server. Un proces server
are în şarjă îndeplinirea unor servicii (executarea unor programe predefinite)
proceselor client. Pentru aceasta este utilizată următoarea schemă:
Procesul server este asociat unei porţi, unde clienţii îşi depun cererile; el este blocat atâta
timp cât nu există cereri de servicii în aşteptare.
Serviciul cerut poate conţine trimiterea la client a rezultatului. În acest caz clientul trebuie
să trimită serverului în cererea sa numărul unei porţi la care el se va bloca în aşteptarea
rezultatului.
În sistemele cele mai simple procesele sunt în număr constant şi create odată pentru
totdeauna la generarea sistemului de operare. În sistemele performante, 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 fiecărei comenzi.
Primitivele de creare şi distrugere a proceselor pot fi puse în şarja sistemului de operare sau
la dispoziţia utilizatorilor. Crearea unui proces presupune alocarea resurselor şi iniţializarea
contextului. 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 operaţii au fost introduse pentru organizarea executării paralele a
programelor pe un sistem multiprocesoral, noţiunea de proces nefiind încă clară.
01.09.20
20 149
12:47:14
4.1. Realizarea excluderii mutuale
Fie {p1, p2,...,pn} o mulţime de procese pe care le vom considera ciclice; programul fiecărui
proces conţine o secţiune critică. Excluderea mutuală este asigurată prin două fragmente de
program (prolog şi epilog), care încadrează secţiunea critică a fiecărui proces. Soluţia
trebuie să posede următoarele proprietăţi:
• excludere mutuală: la fiecare moment de timp cel mult un proces execută secţiunea critică,
• absenţa blocajelor intempestive (care nu sunt la timpul lor): dacă în secţiunea critică nu se
află vreun proces, nici un proces nu trebuie să fie blocat de mecanismul excluderii
mutuale,
• toleranţă la defecte: soluţia trebuie să rămână validă şi în cazul unor defecte în unul sau în
mai multe procese, care se află în afara secţiunii critice,
• absenţa privaţiunilor: un proces, care a cerut intrarea într-o secţiune critică nu trebuie să
aştepte un timp infinit (presupunând, că toate procesele au aceeaşi prioritate),
• simetrie: prologul şi epilogul trebuie să fie identice pentru toate procesele şi independente
de numărul lor.
Pentru tratarea cu ajutorul aşteptării active a cazului în care mai multe procese
actualizează şi consultă variabile comune, unele maşini au o instrucţiune, care
realizează într-o manieră indivizibilă consultarea şi actualizarea unui amplasament
de memorie. Această instrucţiune, adesea numită Test And Set (tas), este utilizată
în sistemele multiprocesorale (în sistemele monoprocesor mascarea întreruperilor
este suficientă pentru asigurarea excluderii mutuale).
Un semafor s este constituit prin asocierea unui contor cu valori întregi, notat s.c., şi a unui fir
de aşteptare, notat s.f. La crearea semaforului contorului i se atribuie o valoare iniţială s0
(s0≥0), şi firul de aşteptare s.f. este vid.
Fie p un proces care execută P(s) sau V(s), iar q un proces care se află în firul de aşteptare s.f.
Algoritmul primitivelor este următorul:
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
Proprietăţile principale ale sincronizării cu ajutorul semafoarelor pot fi deduse din câteva
relaţii invariante: relaţii verificate iniţial şi care rămân neschimbate după executarea
primitivelor P şi V un număr arbitrar de ori.
deoarece valoarea iniţială a lui s.c. este s0, fiecare operaţie P(s) scade din această valoare o
unitate, iar V(s) adaugă 1.
Aceste operaţii, fiind executate în excludere mutuală, nici o modificare nu este pierdută.
Fie nf(s) numărul de “treceri” de către procese a primitivei P(s), adică suma numărului
de executări a lui P(s) fără blocare şi a numărului de deblocări realizate de către
V(s).
01.09.20
20 155
12:47:14
4.1.3.3. Realizarea excluderii mutuale cu ajutorul semafoarelor
Fie nc numărul de procese, care se află în s.c. la un moment concret de timp. Avem:
nc = nf(mutex) – nv(mutex) (4)
Proprietăţile în cauză pot fi verificate aplicând semaforului mutex relaţia (3):
nf(mutex) = min(np(mutex), 1+nv(mutex)) (5)
Excluderea mutuală
Presupunem, că nici un proces nu se află în secţiunea critică. Vom avea în acest caz nc = 0, sau
nf(mutex) = nv(mutex) sau încă
nf(mutex) ≤ 1+nv(mutex)
Conform relaţiei (5):
nf(mutex) = np(mutex) sau
nbloc(mutex) = 0
Proprietatea b este prezentă, ca şi proprietatea c, deoarece nu s-a făcut nici o ipoteză despre
starea proceselor, dacă ele nu se află în secţiunea lor critică.
3). Privaţiune
Algoritmul excluderii mutuale garantează intrarea a exact unui proces în secţiunea critică când
secţiunea critică este liberă. Se poate întâmpla ca un proces particular să fie reţinut pentru un
interval de timp nedefinit: acest fenomen se numeşte privaţiune.
Pentru cazul cel mai frecvent, când firele de aşteptare a semafoarelor sunt gestionate conform
ordinii “prim sosit – prim servit” fără prioritate, riscul de privaţiune este eliminat.
Noţiunea de proces şi operaţiile 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 maşinilor abstracte ierarhice, nucleul
constituie nivelul cel mai inferior, realizat direct pe maşina fizică. Maşina abstractă, realizată
astfel poate fi numită o maşină a proceselor, care posedă, în afara setului de instrucţiuni de
bază, primitivele care permit crearea, distrugerea şi sincronizarea proceselor. Ca şi orice
maşină abstractă, maşina realizată în acest mod ascunde unele proprietăţi ale maşinii fizice.
Astfel:
• noţiunea de proces ascunde utilizatorilor nucleului mecanismul de alocare a procesoarelor fizice. La un
nivel superior nivelului nucleului chiar şi numărul procesoarelor nu intervine decât doar asupra
performanţelor 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.
Este, totuşi, posibil de evidenţiat câteva caracteristici comune ale acestei structuri, pe care le
vom prezenta înainte de a descrie o realizare concretă. 159
01.09.2020 12:47:14
4.2.1. Stările unui proces
Luarea în consideraţie a alocării fizice a unui procesor ne impune să descompunem starea activă
în două stări noi. Un proces activ se numeşte ales, dacă el este în curs de execuţie pe un
procesor fizic; el se numeşte eligibil dacă nu poate fi executat din cauza lipsei unui
procesor disponibil.
blocat
01.09.20 (wait)
20 160
12:47:14
Fig.4.1. Stările unui proces
Mulţimea programelor, care realizează aceşti algoritmi se numeşte planificator (eng.
scheduler, fr. ordonnanceur).
Programul, care realizează alegerea propriu-zisă se numeşte dispecer (eng. dispatcher, fr.
distributeur).
planificator
01.09.20
20 161
12:47:15
4.2.2. Administrarea contextelor şi schemele primitivelor
Conţinutul contextului
Operaţia de alocare a procesorului fizic impune păstrarea pentru fiecare proces a unei copii a
contextului. Această copie a contextului descrie starea procesorului pentru procesul
considerat. În acest scop fiecărui proces i se asociază o mulţime de informaţii rezidente în
memorie şi numită vector de stare, bloc de control al procesului sau blocul contextului,
care conţine:
• informaţiile despre starea procesorului, necesare la realocarea lui,
• valorile atributelor procesului (prioritate, drept de acces),
• pointeri la spaţiul de lucru al procesului (segmentele procedură şi date, stiva de execuţie),
• informaţii de gestiune (starea, legăturile de înlănţuire).
Organizarea nucleului
Execuţia programelor nucleului poate fi declanşată î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 operaţii de sincronizare şi sunt invizibile la nivelurile superioare.
• Asocierea unui concret proces, care tratează o întrerupere. Doar acest proces se va afla în
aşteptarea unei întreruperi anume, existând pentru aceasta o instrucţiune specială.
• Asocierea unei operaţii de deblocare (semnalizare asociată unei condiţii, V la un semafor, etc.)
la o întrerupere.
Primitivele care urmează pot fi aplicate unui proces existent şi executate doar de proc-părinte.
Procedura suspendare(p) întrerupe execuţia unui proces p, plasându-l într-un fir de aşteptare
special. Execuţia lui p poate fi reluată doar cu ajutorul primitivei reluare(p).
01.09.20
Utilizarea primitivelor creare, distrugere, suspendare şi reluare 20este
12:47:15
condiţionată
164 de un drept,
care figurează în atributul drepturi al procesului.
Sincronizarea
Din momentul creării sale unui proces i se asociază un număr fix (nume intern, process
handler), care serveşte la desemnarea lui şi permite accesarea blocului său de
context. Blocul de context conţine următoarele câmpuri:
Csp : zona de salvare a cuvântului de stare a programului,
Reg : zona de salvare a registrelor generale ale procesorului,
Stare : valoarea stării procesului (eligibil, blocat, ...),
Prio : prioritatea procesului,
Drepturi : drepturile procesului,
Fire : legături de înlănţuire în ierarhia proceselor,
Suc : legături de înlănţuire în firele de aşteptare (FA).
01.09.20
20 165
12:47:15
Administrarea proceselor utilizează fire de aşteptare, ordonate în ordinea de descreştere a
priorităţilor şi comandate de un set de proceduri de accesare:
.. legătură de înlănţuire
.
Csp[i]
Reg[i]
Bloc de Stare[i]
context
Drepturi[i]
Prio[i]
.. legături de înlănţuire în FA
.
context în memorie
blocul contextului i
01.09.20
20 166
Fig.4.4. Organizarea unui FA de procese 12:47:15
4.3.2. Realizarea monitoarelor
Monitorul, descris mai jos, în raport cu noţiunea clasică de monitor, prezintă următoarele
diferenţe:
Semantica primitivei semnalizare. Specificarea iniţială a primitivei c.semnalizare precizează că
unul din procesele care sunt în aşteptarea condiţiei 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 competiţie cu alte procese, care
aşteaptă să intre în monitor, şi nu este garantat că va fi imediat ales. Condiţia, care
provocase deblocarea, poate fi modificată înainte ca procesul deblocat să-şi reia execuţia
în monitor. Pentru această nouă interpretare trebuie să fie modificată forma punerii în
aşteptare. O construcţie de forma
if continuare_non_posibilă then
c.aşteptare
endif
devine în acest caz
while continuare_non_posibilă do
c.aşteptare
endwhile
Deşi această construcţie introduce un risc de privaţiune, ea prezintă o serie de avantaje de
ordin practic. Ea evită o comutare a contextului, cu preţul unei evaluări suplimentare a
condiţiei. Dar principalul este că ea permite definirea simplă a unor posibilităţi
suplimentare utile (deblocare multiplă, întârzieri de control sau de gardă).
Verificarea validităţii monitorului este simplificată, deoarece condiţia de depăşire
01.09.20
(continuare_posibilă) este consultată în timpul deblocării: 20 procesul
167care execută
semnalizare poate să se mulţumească cu garantarea unei condiţii mai slabe decât
12:47:15
condiţia de depăşire.
Deblocare multiplă
Problema deblocării multiple poate fi rezolvată uşor introducând o primitivă nouă
c.difuzare_semnal efectul căreia se exprimă astfel:
while c.non_vid do
c.semnalizare
endwhile
Fiind dat, că toate procesele deblocate vor testa din nou condiţia şi cer din nou acces la
monitor, această primitivă va avea evident efectul aşteptat.
Întârziere de gardă.
Din probleme de securitate, în special pentru tratarea blocajelor, poate fi util să se asocieze
o întârziere de gardă condiţiei unui monitor. Această întârziere este egală cu durata
maximă de blocare a unui proces într-un fir de aşteptare asociat condiţiei date. La
expirarea întârzierii de gardă va fi efectuată o tratare specificată. Această tratare poate
consta în simpla deblocare a procesului (care va testa din nou condiţia de depăşire) sau
transferul său într-un fir de aşteptare special.
Fiecărei condiţii c de M îi este asociat un fir M.c.fir, un contor de gardă M.c.întârziere şi,
pentru condiţiile asociate unei întreruperi, un indicator boolean M.c.într_sosită.
c.aşteptare: 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; ieşire(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ă secvenţa prolog asigură salvarea contextului şi intrarea în secţiunea critică,
iar secvenţa alocare_procesor asigură alocarea procesorului şi părăsirea secţiunii critice.
O condiţie poate fi asociată unui singur nivel de întrerupere. Sosirea unei întreruperi provoacă
executarea funcţiei semnalizare pentru condiţia asociată. Prioritatea relativă a
întreruperilor este tradusă în prioritatea proceselor, care tratează întreruperile.
Nu detaliem aici <tratare specifică>, care trebuie să fie specificat de către procesul părinte la
momentul creării procesului descendent. Acest program conţine, evident, codul de
diagnosticare (identitatea procesului generator de eroare, natura erorii), care trebuie
transmis procesului părinte într-un mod special, conform
01.09.20 gradului de urgenţă
20 172
(actualizarea unui indicator, deblocare, etc.). 12:47:15
4.3.3.1. Crearea şi distrugerea proceselor
Pentru alocarea contextelor şi numelor proceselor sunt utilizate două metode principale:
• pentru blocurile contextelor sunt rezervate un număr fix de amplasamente; amplasamentele neutilizate -o valoare
specială (nil) a câmpului stare; blocul este desemnat de un număr, care este numărul utilizat pentru desemnarea
procesului asociat;
• amplasamentele rezervate blocurilor sunt alocate dinamic în memorie; numerele sunt alocate proceselor de asemenea
în mod dinamic şi un tabel de corespondenţă, asociază numărului fiecărui proces adresa în memorie a blocului său de
context.
Contextul iniţial este specificat de către procesul creator: el trebuie să definească valoarea
iniţială a registrelor şi a cuvântului de stare a procesului creat, starea iniţială a spaţiului
de lucru, atributele, cum ar fi prioritatea şi drepturile.01.09.20
Unele câmpuri ale cuvântului de
stare sunt predefinite şi nu pot fi modificate (modul, mascarea 20 întreruperilor,
173 etc.).
12:47:15
Pentru elementele legate de protecţie (drepturile de acces), procesul creat nu poate avea
drepturi superioare drepturilor procesului creator; în caz contrar atributele de protecţie
Distrugerea trebuie să implice eliberarea resurselor. Doar numele şi contextul sunt gestionate
direct de nucleu; celelalte resurse, cum ar fi fişierele, sunt preluate de mecanisme
specifice.
Distrugerea unui proces, care se află în secţiunea critică poate conduce la o blocare. Secţiunile
critice ale monitoarelor sunt gestionate direct de nucleu. Este posibil să se asocieze unui
proces numărul dispozitivului de blocare, care se află în posesia procesului dat (el poate fi
angajat în mai multe apeluri incorporate), şi să diferenţiem distrugerea procesului până
când valoarea acestui număr nu va fi 0. O altă soluţie constă în examinarea periodică a
fiecărui dispozitiv de blocare şi să eliberăm dispozitivul de blocare, dacă procesul care îl
posedă a fost distrus.
În acest caz excluderea mutuală este realizată prin mascarea întreruperilor. Pentru aceasta trebuie pregătită
masca întreruperii în cuvântul de stare, care ar specifica programele asociate primitivelor de tratare a
întreruperilor. Dacă notăm prin proces_ales o variabilă globală, care conţine numărul procesului ales, iar
prin salv_csp locaţiunea în care a fost salvat cuvântul de stare a procesorului la apelarea supervizorului
sau la întrerupere, prologul va fi de forma:
prolog:
<mascarea întreruperilor> -- masca în cuvântul de stare
csp[proces_ales] := salv_csp;
salv_registre(Reg[proc_al]);
Programul dispecerului, care de asemenea realizează ieşirea din secţiunea critică, are grijă să aloce procesorul
primului proces din firul de procese eligibile. Pentru simplificarea manipulării acestui fir este binevenit
să fie introdus aici un proces special cu prioritate joasă, care rămâne tot timpul în coada firului şi nu
poate fi blocat. Acest proces, care poate fi ales doar atunci când el este unicul eligibil, execută o
activitate de fond, care nu este urgentă sau o simplă buclă de aşteptare. El garantează, deci, că firul
proceselor eligibile nu este niciodată vid.
Cuvânt de stare
proc_al Registre
c.fişier
(a) începutul executării c.aşteptare
5 1
p5 p6
Cuvânt de stare
f_eligibil proc_al Registre
Procesor
6 5 3
p1 p2 p3
c.fişier
La terminarea execuției unui proces (normal, forţat sau accidental), el este distrus
eliberând toate resursele, alocate anterior.
Dacă a fost terminată deja execuția procesului descendent, iar procesul părinte nu este
gata să recepționeze de la sistem semnalul despre acest eveniment, descendentul nu
dispare total, ci este transformat în Zombie; în câmpul Stat aceste procese sunt notate
cu litera Z. Procesele Zombi nu cer timp de procesor, dar în tabelul proceselor este
păstrată linia lor şi structurile respective ale nucleului nu sunt eliberate. După
terminarea execuției procesului părinte, procesul Zombi orfan devine pentru o perioadă
scurtă de timp descendentul lui init, ca mai apoi să “moară” definitiv.
Un proces poate să “cadă în hibernare”, fără a putea fi scos din această stare: în câmpul
Stat acest eveniment se va nota prin litera D. Procesele aflate în hibernare nu
reacționează la cererile de sistem şi pot fi distruse doar prin reîncărcarea sistemului.
Demon (daemon) în Linux este numit procesul destinat să lucreze în regim de fond fără
terminal şi care execută anumite operații pentru alte procese (nu obligator pe
calculatorul Dumneavoastră). De obicei, demonii își îndeplinesc în liniște lucrul şi ne
amintim de ei doar în cazul unor situații ieşite din comun: spaţiu insuficient – demonul
singur informând utilizatorul despre aceasta, sau refuz să lucreze şi sunteți întrebat de
șef când se vor termina problemele cu imprimantă .
Pentru multe calculatoare demonii, care servesc procesele altor calculatoare, sunt rar
utilizați din care cauză nu trebuie păstrați constant în memorie cu cheltuieli neraționale
ale resurselor sistemului. Pentru coordonarea lucrului acestora a fost creat un super
demon – inetd (Internet daemon).
01.09.20
20 180
12:47:15
4.4.4. Obținerea informațiilor despre procese
Informaţii utile pune la dispoziţie programul lsof. Acesta returnează lista tuturor
fişierelor, utilizate la momentul curent de către procese, inclusiv cataloagele folosite de
către unele procese în calitate de catalog curent sau catalog rădăcină, bibliotecile
dinamice, încărcate în memorie, etc.
01.09.20
20 181
12:47:15
5.1. Principiile gestiunii informaţiei
5.1.1. Definiţii generale
5.1.2. Interpretarea numelor
5.1.2.1. Construirea căii de acces
5.1.2.2. Structura reprezentărilor. Descriptori
5.1.2.3. Contexte şi medii
5.1.3. Legarea
5.1.4. Protecţia
5.1.4.1. Domenii şi drepturi de acces
5.1.4.3. Problemele protecţiei
5.2. Desemnarea şi legarea fişierelor şi intrărilor-ieşirilor
5.2.1. Căi de acces la un fişier
5.2.2. Desemnarea externă a fişierelor. Cataloage
5.2.2.1. Introducere
5.2.2.2. Organizarea arborescentă
5.2.3. Legarea fişierelor cu fluxurile de intrare-ieşire
5.3. Legarea programelor şi datelor
5.3.1. Etapele de viaţă a unui program
5.3.2. Funcţionarea unui încărcător
5.3.3. Funcţionarea unui editor de legături
5.3.3.1. Legarea prin substituţie
5.3.3.2. Legarea prin înlănţuire 01.09.20
5.4. Mecanisme de gestiune a obiectelor 20 182
5.4.1. Segmentarea 12:47:15
Acest capitol este consacrat studierii principiilor de gestiune a informaţiei în SO.
Noţiunea de obiect formează suportul director al studiului dat.
Concepte de bază: nume sau identificator, cale de acces, legare, protecţia obiectelor.
Aceste noţiuni vor fi utilizate în două domenii importante: desemnarea şi legarea
fişierelor şi legarea programelor şi a datelor.
Informaţia, care circulă într-un sistem de calcul constă din obiecte; obiectele sunt
entităţile asupra cărora sunt efectuate anumite operaţii. Toate operaţiile pot fi clasificate
în patru categorii:
• de creare,
• de modificare,
• de căutare,
• de distrugere a obiectelor.
Fiecare obiect are o reprezentare externă (în afara calculatorului) şi una internă,
determinată de suportul fizic. Un obiect poate fi accesat cu ajutorul funcţiilor de acces.
Schema interpretării este de regulă mai puţin eficace în comparaţie cu schema compilării,
deoarece corespondenţa obiectelor trebuie realizată la fiecare accesare, însă ea convine mai
mult în cazul unei gestionări dinamice a obiectelor.
01.09.20
20 184
12:47:15
Programul unui sistem utilizează nume pentru a desemna obiectele. Numele unui obiect este
o informaţie cu funcţie dublă: pe de o parte permite să se facă distincţia obiectului dat de alte
obiecte; pe de altă parte, el serveşte ca şi cale de acces la obiect.
Numele trebuie să respecte anumite reguli proprii limbajului de programare. Nume sunt
identificatorii, care desemnează variabilele şi procedurile într-un limbaj de programare sau
fişierele într-un limbaj de comandă.
În cazul reprezentării externe un identificator desemnează un anumit obiect, care poate fi o
constantă sau o informaţie ce permite accesul la un alt obiect (obiectul permite referirea unui
alt obiect, fig.5.1).
Program
..
. D obiect/reper Ri
identificator
..
.
obiect
Numim obiect accesibil un obiect căruia i s-a asociat o cale de acces. Numim obiect partajat
orice obiect care este accesibil mai multor utilizatori (eventual cu drepturi de acces
diferenţiate).
01.09.20
20 186
12:47:15
5.1.2. Interpretarea numelor
Obiectele sunt păstrate în amplasamente, iar procesele le pot accesa prin nume. Stabilirea căii
de acces la un obiect prin compunerea funcţiilor de acces ataşate se numeşte legare. Vom spune
că un obiect este legat atunci când pentru el este stabilită calea de acces. În cazul operaţiilor
aritmetice calea de acces asociată unui obiect conduce la o constantă; în cazul listelor sau
parametrilor - la un nume. Legarea se traduce, în ultimă instanţă, prin stabilirea corespondenţei
între identificatori şi adrese.
5.1.2.1. Construirea căii de acces
F1 şi F2 - funcţii de acces, accesul de la o1 la o3 fiind realizat prin compunerea acestor funcţii.
Calea de acces de la o1 la o3 - prin metoda substituţiei sau prin metoda înlănţuirii.
Metoda substituţiei stabileşte o nouă funcţie de acces F3, o3 fiind accesat direct de la o1: o1F3o3.
Avantaj - acces rapid, dar şi dezavantajul că o2 este iremediabil pierdut.
Metoda înlănţuirii cere ca la fiecare accesare a obiectului o3 pornind de la o1 să fie parcursă
calea o1F1o2F2o3. Nu se pierde nici o informaţie, dar accesul este mai lent.
Legare la faza de compilare (obiectele private ale unui program), pentru altele calea de acces
este stabilită într-o fază ulterioară (ob. ext. şi parametrii sunt obiecte libere după compilare).
Operaţia de legare a externilor se numeşte editare de legături. Ea poate fi realizată într-o fază
distinctă, premergătoare fazei de execuţie (static), sau în faza de execuţie (dinamic), când se
face prima referinţă la obiectul extern.
Editarea legăturilor se face prin înlănţuire sau prin metoda substituţiei.
187
01.09.2020 12:47:15
Segment - ansamblu de amplasamente consecutive în care se reprezintă obiecte de
acelaşi tip, cu aceeaşi durată de existenţă şi cu acelaşi grad de protecţie.
Segmentul - cea mai mică unitate care poate fi partajată şi poate conţine obiecte
compuse - un masiv, un fişier, o stivă sau o procedură - accesibile procesului la un
anumit moment.
Obiectului procedură îi sunt asociate mai multe noţiuni: modul sursă, modul obiect
sau modul executabil.
Modulul sursă al unei proceduri este textul acesteia scris de către programator într-
un limbaj de programare şi care va fi tratat de către compilator.
Modulul obiect este obţinut la ieşirea compilatorului: este un produs al
compilatorului. Modulul obiect este reprezentat într-un segment sau într-un fişier,
destinat interpretării (după editarea legăturilor, la necesitate) de către procesor ca
instrucţiuni, valori etc., fiind manipulat în consecinţă.
Pentru a separa gestiunea resurselor de administrarea informaţiei s-a introdus
noţiunea de memorie fictivă: memorie operativă ipotetică suficient de mare pentru a
conţine toate obiectele sistemului.
Memoria fictivă este asociată sistemului, memoria virtuală este proprie procesului.
Considerente din care mulţimea obiectelor accesibile unui proces variază în timp:
• Decompoziţia aplicaţiilor
• Gestiunea dinamică
• Protecţia
• Eficacitatea
Trebuie să luăm în consideraţie atât posibilitatea evoluţiei dinamice a mulţimii obiectelor, cât şi
a căilor de acces la aceste obiecte.
Mediul de execuție - mulţimea formată din lexică şi informaţiile (programe, date, reguli de
interpretare) necesare la utilizarea acestei lexici. Aceste informaţii pot lua diferite forme în
dependenţă de limbajul utilizat (limbaj de comandă, limbaj de programare).
ident.
context
reguli de
lexica interpretare obiect
cale de acces
mediul
Fig.5.3. Contextul de execuţie a unui proces 191
01.09.2020 12:47:15
Starea de execuţie a unui proces (“valoarea” obiectelor contextului său) se poate modifica la
execuţia fiecărei instrucţiuni, însă conţinutul contextului său (identitatea obiectelor care-l
formează), se schimbă cu o frecvenţă mai mică.
Examinând aceste cazuri putem diferenţia durata de viaţă a unui obiect, a unui identificator,
care desemnează acest obiect şi cea a unei căi de acces, care conduce la obiectul în cauză.
01.09.20
20 194
12:47:15
5.1.4. Protecţia
Protecţie - mulţimea metodelor şi mecanismelor, care vizează specificarea regulilor
de utilizare a obiectelor şi garantează respectarea acestor reguli.
Protecţia este asigurată de o combinaţie de dispozitive fizice şi logice. Există
legături strânse între desemnarea obiectelor şi protecţia lor.
Trei observaţii, legate de protecţie:
• O modalitate simplă de a interzice unui proces orice acces la un obiect constă în
suprimarea tuturor căilor de acces la acest obiect (retragere din contextul
procesului).
• Atunci când operaţiile permise asupra unui obiect sunt specificate prin
apartenenţa la o clasă sau un tip, este posibilă verificarea prealabilă execuţiei
(adică în momentul compilării sau editării legăturilor) dacă obiectul este utilizat
conform regulilor specificate,
• În cazul în care verificarea este făcută în momentul execuţiei, o procedură de
acces facilitează implementarea verificării şi reduce riscul unor erori. Această
procedură poate fi la nivel logic (un interpretor, de exemplu) sau fizic (un
dispozitiv va aproba trecerea mai departe).
01.09.2020 12:47:15 195
5.1.4.1. Domenii şi drepturi de acces
Un proces este întotdeauna executat într-un domeniu bine definit; contextul său
este cel ataşat domeniului, procesul posedând drepturile specificate asupra tuturor
obiectelor acestui context.
Un proces poate schimba domeniul cu ajutorul unei operaţii particulare (apelare
domeniu). Un domeniu este el însuşi un obiect asupra căruia poate fi executată
operaţia de apel.
01.09.2020 12:47:15 196
Domeniile de protecţie pot fi definite prin mai multe modalităţi; exemplificăm câteva mai jos.
un domeniu pentru sistemul de operare, unul pentru fiecare utilizator,
un domeniu pentru fiecare subsistem, care realizează o funcţie particulară,
un domeniu pentru fiecare mediu (definit, de exemplu, de cuplul (procedură, catalog curent)).
Alegerea depinde de funcţiile cerute şi, cel mai important, de mecanismele disponibile.
Presupunem pentru început, că există un număr constant de obiecte. Regulile de protecţie pot fi
reprezentate sub forma unui tablou bidimensional, numit matricea drepturilor. Acest tablou
conţine câte o linie pentru fiecare domeniu Di şi câte o coloană pentru fiecare obiect Oj
(notăm, că domeniile, fiind obiecte particulare, apar de asemenea şi în coloane). Caseta (i,
j) conţine drepturile pe care le are un proces, care se execută în domeniul Di, asupra unui
obiect Oj.
01.09.2020 12:47:15
Reprezentarea coloanelor: lista de acces
Lista de acces, asociată unui obiect este o listă (Di, <di>), unde Di este un domeniu, care conţine
obiectul, iar <di> este mulţimea drepturilor acestui domeniu asupra lui.
O metodă frecvent utilizată pentru a reprezenta mai compact listele de acces constă în
specificarea pentru un obiect a unor drepturi implicite (default) pe care le posedă fiecare
domeniu. De exemplu, putem specifica implicit, că orice fişier este accesibil doar pentru lectură
fiecărui utilizator. Lista de acces va conţine doar cuplurile (Di, <di>) pentru care drepturile
diferă de cele implicite.
Reprezentarea liniilor: lista de drepturi
Lista drepturilor asociată unui domeniu este o listă (Oj, <dj>) în care Oj desemnează un obiect,
care figurează în contextul domeniului, iar <dj> este mulţimea drepturilor domeniului asupra lui
Oj. Un proces, care este executat în domeniul considerat, primeşte această listă de drepturi; la
fiecare accesare a unui obiect mecanismul de accesare trebuie să verifice că operaţia curentă
este licită, adică este în <dj>. Din considerente de eficacitate, este de dorit ca acest mecanism
să fie cablat. Forma cea mai primitivă în acest sens este bitul supervizor-slave a cuvântului de
stare a unui procesor.
O operaţie importantă este cea de schimbare a domeniului, care permite unui proces să-şi
modifice mediul şi drepturile asupra obiectelor. Pentru a garanta respectarea regulilor de
protecţie, trebuie luate măsuri de precauţie de fiecare dată, când are loc extinderea drepturilor.
Această circumstanţă se poate produce în egală măsură atât la apel, cât şi la retur. Pentru
controlarea operaţiei de schimbare, se cere ca apelul şi returul domeniului să se facă în mod
exclusiv prin execuţia unor proceduri speciale (ghişeu de apel sau de retur), programele cărora
01.09.20
garantează respectarea regulilor specificate. 20 198
12:47:15
5.2. Desemnarea şi legarea fişierelor şi intrărilor-ieşirilor
Vom examina modul de desemnare a fişierelor, legarea lor cu programele, care le utilizează şi
relaţiile lor cu intrările-ieşirile. Ne va interesa organizarea unui fişier ca un tot întreg.
5.2.1. Căi de acces la un fişier
Un fişier este un obiect compus: el posedă un descriptor, care conţine informaţiile, necesare
localizării sale fizice şi realizării funcţiilor de acces. Pentru SO, numele descriptorului unei fişier
permite accesul la fişier. Acest nume al descriptorului, de obicei necunoscut de utilizatori şi
rezervat doar pentru SO, este numit nume intern al fişierului. Descriptorul şi numele intern al
fişierului sunt unice.
Un fişier este desemnat de către utilizatorii externi cu ajutorul identificatorilor – nume externe.
Aceste nume externe sunt definite într-un mediu comun mai multor utilizatori. Structurile de
date, care permit construirea căii de acces la un fişier pornind de la unul din numele sale
externe, sunt numite cataloage, mape, foldere sau directorii.
În afara numelor interne şi externe, adesea mai este definit un nume, zis local sau temporar. Un
nume local este definit într-un mediu propriu unui utilizator şi are o existenţă doar temporară
Legarea numelor locale este realizată prin înlănţuire: un nume local desemnează un descriptor
local, care la rândul său, direct sau indirect, reperează descriptorul unic al fişierului.
Mediul global Mediul local Mediul SGF
Am prezentat mai sus diferite momente în care poate fi stabilită legătura dintre instrucţiunile şi
datele unui program. Vom prezenta în rezumat cele mai frecvente scheme înainte de a trece la
realizarea lor. Această prezentare vizează, în principal, expunerea folosirii noţiunii de legare,
fără a detalia aspectele tehnice ale funcţionării unui încărcător sau editor de legături.
1. Program interpretat date
rezultatul
Compararea acestor două scheme pune în evidenţă diferenţa importantă între
interpretare şi compilare: modificarea unui program interpretat are efect imediat, în timp ce în
cazul compilării suntem nevoiţi să parcurgem toate etapele, începând cu translatarea.
Program compus
Constituirea unui program unic, pornind de la programe construite independent, se realizează
pornind de la programe obiect în adrese relative (deplasabile), adică obţinute după translatare,
prin legarea referinţelor externe. Această operaţie poate fi combinată cu încărcarea.
01.09.2020 12:47:15 202
5.3.2. Funcţionarea unui încărcător
Un încărcător este destinat să pună în formă absolută un program (sau modul) obiect în adrese
relative. Această operaţie constă în înlocuirea tuturor adreselor relative la originea
modulului prin adrese absolute. Pentru aceasta se va efectua un lucru preliminar în faza de
translatare: înregistrărilor modulului obiect, care conţin o adresă translatabilă, li se va
ataşa un indicator, care va fixa poziţia acestei adrese în interiorul înregistrării (dacă poziţia
nu este specificată în mod implicit). Adresele translatabile pot să apară:
• sau în câmpul de adresă al instrucţiunii,
• sau în cazul datelor, în ”expresii pentru calcularea adresei”, destinate a fi utilizate ca
relaţii de direcţionare sau să fie încărcate în registrele de bază.
Încărcătorul utilizează metoda substituţiei: orice adresă relativă a este înlocuită prin adresa
absolută a+originea, unde originea este adresa absolută începând cu care este încărcat
modulul.
Pentru cazuri mai generale, modulul poate avea mai multe puncte de intrare, desemnate cu
ajutorul identificatorilor; el va conţine în acest caz un tabel al punctelor de intrare,
construit de translator, care asociază o adresă relativă01.09.20
fiecărui identificator. Aceste adrese
sunt transformate în adrese absolute; adresa punctului de20intrare203
12:47:15
este determinată pornind
de la identificator prin intermediul unei căutări în tabel.
Pentru a ilustra prezentăm un format posibil al unui modul obiect translatabil şi programul
corespunzător al încărcătorului.
en-tête <id_modul, lungime,...>
...
corpul modulului <adr, n, r, cod>
...
...
tabelul punctelor de intrare <identificator, adresă relativă>
...
O înregistrare a corpului modulului este de forma <adr, n, r, cod> cu
adr : adresa relativă a codului <cod> în modul
n : lungimea lui <cod> în octeţi
r : 1 sau 0 (cod translatabil sau nu)
cod : n octeţi ai programului.
01.09.20
20 204
12:47:15
Algoritmul încărcătorului poate fi următorul:
Interpretarea Interpretarea
numelor locale numelor externe
Nume Realizarea
interne funcţiilor de acces
logic
01.09.20
20 217
12:47:15
Principalul avantaj al metodei adresării dispersate (dacă se reuşeşte să se asigure un nivel
acceptabil al coliziunilor) este rapiditatea: în lipsa coliziunilor găsirea unei înregistrări necesită o
singură accesare a discului.
Totuşi, în cazul cel mai frecvent, când mulţimea cheilor este ordonată, funcţia de dispersare nu
întotdeauna asigură o relaţie simplă între ordinea cheilor şi ordinea adreselor logice a
înregistrărilor respective.
Metodele accesului indexat permit remedierea acestui inconvenient.
218
01.09.2020 12:47:15
Fişiere indexate
Metodele accesului indexat sunt utilizate în cazul când mulţimea cheilor este ordonată. Relaţia
dintre cheie şi adresa logică este materializată printr-un tabel, numit tabel al indicilor, în care
ordinea cheilor este semnificativă. Schema principiului organizării indexate este dată de fig.6.4
Schemele utilizate efectiv în practică sunt mai complexe pentru a permite:
• accelerarea căutării în cadrului indicelui,
• facilitarea inserării şi a suprimării înregistrărilor.
01.09.20
20 222
12:47:15
6.3.1. Implantare secvenţială (contiguă)
În acest caz fiecare fişier ocupă o mulţime de blocuri consecutive în memoria
secundară. Este unicul mod de implantare în cazul unei benzi magnetice: fişierele
sunt aranjate consecutiv pe bandă, fiecare fiind separat de următorul cu ajutorul
unui simbol, numit sfârşit de fişier (end of file, EOF). Un EOF dublu marchează
sfârşitul părţii utilizate a benzii. Descriptorul unui fişier este plasat la începutul
fişierului şi, adesea, repetat la sfârşitul fişierului. În interiorul fişierului
înregistrările sunt aranjate consecutiv; dacă lungimea lor este variabilă, ea va fi
prezentă la începutul fiecărei înregistrări. Caracterul EOF este detectat în mod
automat de controlerul mecanismului de derulare a benzii. O operaţie “căutarea
EOF-ului fişierului” permite saltul de la un fişier la altul pentru căutarea unui fişier
cu numele dat.
Implantarea secvenţială poate fi în egală măsură folosită şi pentru discuri.
Avantajul principal constă în garantarea unui acces secvenţial eficient
(informaţiile cu adrese logice succesive sunt implantate în blocuri adiacente)
permiţând în acelaşi timp un acces direct eficient (calcularea adresei fizice
pornind de la adresa logică este foarte simplă şi nu cere accesarea discului).
Totuşi, această metodă prezintă inconveniente grave în cazul în care crearea,
distrugerea sau modificarea lungimii unui fişier sunt operaţii frecvente.
Implantarea contiguă pe disc este utilizată pentru fişierele numărul şi lungimea
cărora nu variază (de exemplu, fişiere create odată pentru totdeauna şi utilizate
mai apoi doar pentru consultare); sisteme primitive pentru microcalculatoare,
când simplitatea realizării este un factor preponderent.
01.09.2020 12:47:15 223
6.3.2. Implantare non contiguă
Dacă abandonăm restricţia contiguităţii implantării, memoria secundară se transformă într-o
resursă banalizată, blocurile memoriei secundare fiind echivalente din punctul de vedere al
alocării lor.
6.3.2.1. Blocuri înlănţuite
01.09.20
20 226
12:47:15
Fig.6.9. Tabel de implantare cu două
nivele
6.3.3. Alocarea memoriei secundare
Problema alocării memoriei secundare poate fi pusă în termeni similari cu cea a memoriei
principale; restricţiile principale sunt:
• alocarea prin blocuri de lungime fixă,
• costul ridicat al accesului,
• caracteristicile proprii fiecărui suport: piste, dispozitive de citire-scriere mobile sau fixe.
Structura de date cel mai des utilizată pentru a descrie starea de ocupare a memoriei este un
lanţ de biţi, bitul cu numărul i indicând starea (ocupat sau liber) a blocului cu acelaşi număr.
Acest tabel de ocupare poate atinge dimensiuni importante; de exemplu, sunt necesari 12,5 Ko
pentru a descrie ocuparea unui disc de 200 Mo alocaţi prin blocuri de 2 Ko. Pentru a spori
eficienţa algoritmilor de alocare tabelul poate fi organizat pe mai multe niveluri.
227
01.09.2020 12:47:15
6.4. Realizarea funcţiilor de acces elementar
6.4.1. Organizarea descriptorilor
Un descriptor de fişier trebuie să conţină informaţii diverse:
• informaţii pentru localizarea fizică,
• informaţii referitoare la utilizare,
• informaţii asociate protecţiei şi securităţii.
6.4.1.1. Localizarea fizică
Dacă aceste informaţii sunt de dimensiune fixă şi redusă (implantare contiguă, blocuri
înlănţuite) ele se conţin direct în descriptor; în caz contrar (tabele de implantare înlănţuite sau
pe mai multe niveluri), descriptorul conţine doar un pointer la tabelul de implantare şi nişte
informaţii sintetice, cum ar fi dimensiunea fişierului, dimensiunea tabelului de implantare, etc.
6.4.1.2. Informaţii de utilizare
Informaţiile, legate de utilizarea unui fişier pot fi clasificate după cum urmează:
• Informaţii de stare. Aceste informaţii definesc starea curentă a fişierului: deschis sau
închis, gradul de partajare, disponibilitatea pentru modificare, etc.
• Informaţii despre conţinutul fişierului. Aceste informaţii permit interpretarea conţinutului
fişierului. Este posibil să se asocieze unui fişier un tip, care specifică operaţiile permise.
• Informaţii despre structura logică. Aici pot fi plasate informaţiile care permit trecerea de la
structura logică la structura fizică a fişierului. De exemplu, în cazul înregistrărilor de
lungime fixă este convenabil să se aleagă lungimea înregistrării multiplu sau submultiplu al
lungimii blocului fizic. Raportul lungimea blocului/lungimea înregistrării, adesea numit
factor de bloc, figurează în cadrul descriptorului.
• Informaţii despre utilizările precedente. Aceste informaţii pot fi de natură statistică
(numărul deschiderilor, accesărilor, intervalul mediu timp 01.09.20de între accesări, gradul mediu
de partajare, etc.) şi au scopul de a înţelege mai bine funcţionarea
20
12:47:15
sistemului pentru
228
ameliorarea lui.
Ca şi majoritatea funcţiilor unui sistem de operare, aceste primitive pot fi
apelate în două moduri: cu ajutorul unor instrucţiuni sau prin apelarea regimului
supervizor.
01.09.20
20 229
12:47:15
6.4.2.1. Crearea
Specificarea interfeţei
Parametrii furnizaţi sunt:
numele fişierului
tipul (opţional)
lungimea (opţional)
starea iniţială (opţional)
Cel mai frecvent, parametrii starea iniţială şi lungimea nu sunt furnizaţi, având valori
implicite: lungimea = 0, fişierul este închis, lista de acces predefinită.
Operaţii
• să se creeze un descriptor pentru fişier, obţinem astfel un nume intern,
• dacă numele furnizat este un nume extern, să se creeze o intrare a acestui nume în
catalogul curent,
• să se aloce memorie fişierului; chiar dacă lungimea sa este nulă, un fişier conţine un
antet, care ocupă primul său bloc,
• să se iniţializeze descriptorul cu informaţiile de localizare, lungime, protecţie (lista
drepturilor iniţiale de acces),
• dacă descriptorul nu se conţine direct în catalog, să se introducă o intrare în catalog
cu numele intern al fişierului (adresa descriptorului).
Cazuri anormale
• nume furnizat incorect (incorect construit sau care desemnează un fişier deja
existent);
• memorie insuficientă în memoria secundară. 01.09.20
20 230
Fişierul nu poate fi creat şi situaţia anormală este semnalată.
12:47:15
6.4.2.2. Distrugerea
Specificarea interfeţei
Unicul parametru furnizat este numele fişierului. Efectul operaţiei este de a suprima
orice acces ulterior la fişier, invalidând toate numele acestuia şi eliberând toate
resursele pe care fişierul le utilizează (intrări în tabele, memorie).
Operaţii
• să se elibereze toată memoria, care a fost alocată fişierului;
• să se elibereze memoria alocată descriptorului şi numele intern să devină reutilizabil;
• suprimarea numelui extern al fişierului în catalogul, care-l include, de asemenea,
dacă este cazul, în tabelul numelor locale.
Ultima operaţie poate fi destul de delicată, dacă există mai multe căi de acces la fişier.
Poate fi utilizată una din următoarele soluţii:
• dacă căile multiple de acces sunt legături, nu se va lua nici o măsură; un acces
ulterior prin una din aceste legături va conduce la numele extern. Inexistenţa
fişierului va fi detectată (cu excepţia cazului în care un fişier cu acelaşi nume a fost
creat în intervalul de timp dat);
• dacă căile multiple de acces sunt nume (ceea ce se poate produce, dacă structura
catalogului nu este o arborescenţă) vor fi utilizate sau legături inverse (metodă
costisitoare), sau un contor al referinţelor păstrat în descriptor, care duce evidenţa
numărului căilor de acces.
Un fişier poate fi distrus doar dacă există o singură cale de acces. Această soluţie este
utilizată, de exemplu, în sistemul Unix.
01.09.2020 12:47:15 231
6.4.3.1. Deschiderea
Specificarea interfeţei
Parametrii operaţiei de deschidere sunt:
numele fişierului, condiţiile de utilizare: modul de acces (citire, scriere, execuţie, etc.),
procedurile de acces (secvenţial, direct, sincron, etc.), parametrii de transfer (tampoane,
etc.)
Scopul - de a pune un fişier în starea în care accesul este posibil conform modului specificat.
Această operaţiei este de dublă utilitate pentru SGF:
Protecţie. SGF poate să controleze:
la deschidere, dacă utilizatorul este autorizat să acceseze fişierul în condiţiile specificate,
la fiecare accesare a fişierului, dacă condiţiile de acces sunt compatibile cu cele specificate la
deschidere,
în caz de partajare, dacă condiţiile de accesare ale utilizatorilor sunt reciproc compatibile.
Eficienţă. SGF poate să accelereze accesul la fişierele deschise, aducând în memorie descriptorii
lor, tabelele de implantare şi textele procedurilor de acces. Fişierul însuşi poate fi
transferat, eventual, pe un suport cu acces mai rapid; dacă el se află pe un suport amovibil
nemontat, montarea este necesară.
Operaţii
La deschidere vor fi realizate următoarele operaţii:
localizarea fişierului şi, eventual, transferarea lui pe un suport mai rapid,
controlarea dreptului utilizatorului de a deschide fişierul în modul specificat,
crearea unui descriptor local şi atribuirea unui nume local,
alocarea eventuală a memoriei pentru zonele tampon de intrare-ieşire.
01.09.20
Cazuri anormale 20
12:47:15
232
condiţii de deschidere incompatibile cu drepturile utilizatorului, imposibilitatea deschiderii,
datorată restricţiilor specificate pentru partajare, lipsa spaţiului în memorie.
6.4.3.2. Închiderea
Specificarea interfeţei
Unicul parametru necesar este numele fişierului. Efectul operaţiei este de a interzice orice acces
ulterior la fişier şi de a-l transfera într-o stare coerentă şi stabilă, redându-i definitiv toate
modificările operate în perioada cât a fost deschis.
Operaţii
Descriptorul fişierului este actualizat (dacă aceasta nu a fost făcut anterior) pentru a înregistra
definitiv modificările operate în perioada cât a fost deschis; descriptorul local este
suprimat, numele local putând fi reutilizat. Memoria ocupată de zonele tampon şi
procedurile de intrare-ieşire este eliberată, dacă ea a fost alocată doar pentru perioada de
deschidere a fişierului. Fişierul este, eventual, transferat pe suportul său de origine; o
cerere de demontare este trimisă dacă suportul de origine este amovibil.
Unele sisteme operează cu fişiere temporare, adică fişiere desemnate doar de numele local. La
închiderea unui astfel de fişier, utilizatorul are de ales între două posibilităţi:
să catalogheze fişierul, atribuindu-i un nume extern; fişierul va fi în acest caz salvat.
(implicit) să nu facă nimic, fişierul fiind distrus în acest caz.
Cazuri anormale
Pentru garantarea coerenţei fişierului, în timpul închiderii nu trebuie să aibă loc operaţii de
transfer (a descriptorului sau a fişierului).
01.09.20
20 233
12:47:15
6.4.4. Acces elementar la informaţii
Accesul elementar (citire sau scriere) la o înregistrare a fişierului constă din două etape:
01.09.20
20 234
12:47:15
6.5.1. Despre securitate şi protecţie
Cu titlul securitate vom îngloba mulţimea metodelor, care sunt chemate să garanteze execuţia
tuturor operaţiilor asupra unui fişier în conformitate cu specificaţiile lor, chiar în cazul unor
defecte în cursul execuţiei, şi că informaţiile conţinute într-un fişier nu sunt alterate, dacă nici o
operaţie nu a fost executată. Metodele utilizate sunt, în caz general, cele care asigură toleranţa
sistemului la defecte; baza lor este redundanţa informaţiilor.
Prin protecţie vom înţelege mulţimea metodelor chemate să specifice regulile de utilizare şi să
garanteze respectarea lor. O descriere succintă a metodelor principale de protecţie a fost adusă
în 5.1.4. Ele se bazează pe noţiunea de drept de acces şi existenţa unui mecanism, care permite
să se garanteze conformitatea operaţiilor drepturilor de acces specificate.
01.09.20
20 235
12:47:15
6.5.2. Securitatea fişierelor
Securitatea fişierelor este asigurată, după cum a fost menţionat, prin redundanţa informaţiilor.
Redundanţa poate fi introdusă în două moduri: salvarea periodică a unor informaţii, pentru a
putea restabili o stare anterioară în caz de distrugere, şi redundanţa internă, care permite
reconstituirea unor informaţii devenite incoerente din cauza unui accident de origine fizică sau
logică, care a provocat o alterare parţială.
6.5.2.1. Redundanţa internă şi restabilirea informaţiilor
Principiul redundanţei interne constă în organizarea structurilor de date astfel, încât orice
informaţie să poată fi obţinută prin cel puţin două căi distincte. Se reduce astfel probabilitatea
că distrugerea accidentală a unei părţi a informaţiei va conduce la pierderea iremediabilă a
conţinutului fişierului.
Tehnicile frecvent utilizate în acest scop sunt următoarele:
pentru un fişier păstrat pe disc în blocuri înlănţuite se va folosi înlănţuirea dublă, se va include
în fiecare bloc un pointer la blocul, care conţine descriptorul, sau indicaţia că blocul este liber,
se va include în descriptor numele simbolic al fişierului şi un pointer la catalogul în care se
conţine fişierul, o parte a descriptorului va fi dublată.
6.5.2.2. Salvare periodică
Se poate apriori conveni să fie salvate, la intervale regulate de timp, toate informaţiile conţinute
într-un SGF. Poate fi realizată salvarea doar a modificărilor, care au avut loc pentru ultima
perioadă, concomitent cu lucrul normal al sistemului.
01.09.20
20 236
12:47:15
6.5.3. Protecţia fişierelor
01.09.20
20 237
12:47:15
7. Alocarea resurselor
7.1. Noţiuni generale
7.1.1. Definiţii
7.1.2. Probleme în alocarea resurselor
7.1.3. Exemple de sisteme cu fire de aşteptare
7.2. Modele pentru alocarea unei resurse unice
7.2.1. Alocarea procesorului
7.2.1.1. Introducere
7.2.1.2. Prim sosit, prim servit
7.2.1.3. Cererea cea mai scurtă servită prima
7.2.1.4. Caruselul şi modele derivate
7.3. Tratarea blocărilor
7.3.1. Enunţul problemei
7.3.2. Algoritmi de prevenire
7.3.2.1. Algoritmi de profilaxie
7.3.2.2. Algoritmul bancherului
7.3.3. Algoritmi de detectare şi tratare
În acest capitol prezentăm principiile de alocare a
resurselor într-un SI. Sunt abordate două aspecte:
01.09.20
20 239
12:47:15
7.1. Noţiuni generale
7.1.1. Definiţii
Resursă - orice obiect, care poate fi utilizat de un proces. Unei resurse îi sunt asociate proceduri
de acces, care permit utilizarea resursei, şi reguli de utilizare - “modul de utilizare”.
Nu există vre-o diferenţă fundamentală între noţiunea de obiect şi cea de resursă. Folosirea celor doi termeni semnifică
mai mult o diferenţă de domeniu: se utilizează noţiunea obiect atunci când ne interesează specificarea şi realizarea
obiectului şi a funcţiilor sale de acces, iar resursă pentru problemele de alocare şi partajare.
O resursă este alocată unui proces dacă procesul poate utiliza resursa, folosind procedurile ei de
acces. Legarea unei resurse de un proces poate fi implicită sau explicită. În primul caz, este
suficientă trecerea procesului într-o anumită stare pentru ca el să devină candidat la utilizarea
resursei; în cel de-al doilea caz, solicitarea trebuie să fie formulată explicit sub forma unei cereri
adresate unui alocator al resursei.
Alocatoarele şi cererile pot lua forme diverse: de exemplu, un alocator poate fi un proces căruia
cererile îi sunt transmise prin emiterea unor mesaje; sau chiar un monitor o procedură a căruia
serveşte la emiterea unor mesaje.
Reacţia unui alocator la o cerere poate de asemenea fi diferită: alocarea resursei solicitate, refuz
cu sau fără blocarea procesului solicitant. Terminarea utilizării unei resurse de către un proces
poate la fel lua diferite forme: eliberarea explicită sau implicită a resursei sau retragerea forţată
a resursei de către alocator.
Exemplul 7.2. Memoria principală. Alocarea memoriei principale pune în funcţie două
mecanisme distincte:
Alocarea explicită: este mecanismul de obţinere a unei zone de memorie fie de către un program
în curs de execuţie, fie de către sistemul de operare înaintea încărcării unui program nou.
Alocarea implicită: pentru acest mod de alocare cererea este emisă în momentul executării unei
instrucţiuni, când adresa emisă de procesor este adresa unui amplasament nealocat
procesorului. Acest mecanism stă la baza realizării memoriei virtuale. ◄
Exemplul 7.3. Memoria secundară. Memoria secundară este alocată prin blocuri banalizate
de lungime fixă. Alocarea şi eliberarea poate fi explicită sau implicită (de exemplu,
extinderea unui fişier provoacă emiterea unei cereri pentru un bloc suplimentar). ◄
Exemplul 7.4. Linii de comunicaţie. Dacă mai multe procese partajează serviciile unui
dispozitiv de intrare-ieşire comun (o imprimantă sau o linie de comunicaţie, de exemplu),
cererile sunt transmise sub formă de mesaje unui proces, numit server, care administrează
acest dispozitiv. Fiecare mesaj conţine informaţiile necesare execuţiei transferului cerut.
Mesajele sunt administrate cu ajutorul unui fir de aşteptare
01.09.20 cu sau fără priorităţi. ◄
20 241
12:47:15
7.1.2. Probleme în alocarea resurselor
Obiectivul unui sistem de alocare a resurselor este să satisfacă cererile într-un mod echitabil,
asigurând în acelaşi timp şi performanţe acceptabile. Dacă toate procesele au aceeaşi
prioritate, o alocare este echitabilă, atunci când este asigurată o tratare asemănătoare
fiecărui proces, de exemplu, aşteptarea medie este identică. Dacă între procese există
priorităţi, este dificil să se definească noţiunea de echitate în caz general, dar ea poate fi
exprimată prin faptul, că calitatea serviciului (măsurată, de exemplu, prin valoarea inversă
a timpului mediu de aşteptare sau printr-o altă expresie semnificativă) este funcţie
crescătoare de prioritate, două procese de aceeaşi prioritate beneficiind de aceeaşi tratare.
Unii algoritmi de alocare conţin riscul de a face un proces să aştepte la infinit - privaţiune.
Dacă resursele sunt utilizate de mai multe procese pot avea loc două fenomene nedorite:
• Blocarea - este stoparea a mai multor procese pentru un interval de timp nedefinit, fiecare
dintre procese fiind în aşteptarea eliberării resurselor alocate altor procese.
• Căderea –o cerere excesivă a unui oarecare tip de resurse conduce la degradarea
performanţelor sistemului.
Vom presupune, că alocarea se va face în mod centralizat, adică algoritmii utilizaţi ştiu situaţia
de alocare a mulţimii resurselor la orice moment.
Un sistem informatic este constituit din N instalaţii identice, fiecare fiind descrisă de modelul
M/M/1, cu parametrii λ şi μ (fig. 7.1a). Vom examina influenţa asupra timpului de răspuns
al acestui sistem a utilizării comune a resurselor, caracteristicile totale de tratare fiind
constante.
Prioritatea unui proces este o informaţie, care permite clasificarea procesului în cadrul altor
procese, dacă trebuie făcută o alegere.
Variabila principală, care prezintă interes este timpul mediu de răspuns. Cererea este
caracterizată de repartiţia intervalelor de sosire şi de timpul de servire.
Din practică este cunoscut, că un utilizator suportă cu atât mai greu aşteptarea servirii unei
cereri cu cât lucrul trimis de el este de durată mai mică; aceasta este adevărat atât pentru
lucrul interactiv, cât şi pentru cel de fond. Din aceste considerente metodele de alocare a
procesorului au drept scop reducerea timpului mediu de aşteptare a lucrărilor celor mai
scurte.
01.09.20
Ele diferă conform modului de estimare a duratei lucrărilor 12:47:15
şi în20dependenţă
244 de privilegiile
acordate lucrărilor funcţie de această durată estimată.
7.2.1.2. Prim sosit, prim servit
Disciplina “PSPS” (FIFO) utilizează un fir unic, fără prioritate şi fără retragere. Procesul ales este
executat până la terminarea sa, iar cel care va urma este procesul din topul firului de
aşteptare. Un proces nou intră în coada firului.
tm
Var(ts
)
1 ρ=λts
Fig.7.2. Timpul mediu de răspuns pentru
Variaţia timpului mediu de răspuns f de încărcarea sistemului şi de variaţia timpului de servire.
Putem remarca:
• creşterea rapidă a timpului mediu de răspuns, atunci când sistemul
01.09.20 se apropie de saturaţie: un sistem
este cu atât mai sensibil la o variaţie a şarjei, cu cât este mai 12:47:15
ridicat
20 ρ, 245
• influenţa dispersiei timpilor de servire asupra timpilor de răspuns.
Aceste două efecte pot fi întâlnite în toate disciplinele de alocare.
7.2.1.3. Cererea cea mai scurtă servită prima
În acest caz cererile sunt ordonate în cadrul firului de aşteptare conform timpului lor de servire,
presupus apriori cunoscut, cererile cu durata de servire cea mai scurtă aflându-se în top.
Timpul mediu de aşteptare tm funcţie de timpul de servire ts este dat de formula (7.2):
t m (1 C t )
2 2 ts
tm(ts) = s s
cu (t s ) tdB ((7.2)
t)
2[1 (t s )] 2 0
tm(ts) ≈ (7.3)
s s
pentru valori mari ale ts, unde ρ(ts) este aproape de λtms, fie ρ:
t m (1 C t )
2 2
tm(ts) ≈ (7.4)
s s
2(1 ) 2
01.09.20
20 246
12:47:15
CSSP are două dezavantaje: ea prezintă un risc de privaţiune
pentru cererile lungi, dacă rata de sosire a cererilor scurte
este ridicată şi necesită cunoaşterea apriori exactă a ts. tm
CSSP
Evitarea riscului de privaţiune - cererilor priorităţi care vor
creşte odată cu creşterea timpului lor de aflare în firul de
aşteptare, prioritatea iniţială fiind determinată de timpul de FIFO
servire estimat.
Disciplinei HRN (Highest Response Ratio Next) prioritatea
unei cereri la un moment de timpτ
p(t) = [t(τ)+ts)]/ts (7.5) ts
unde t(τ) este timpul de aflare a unei cereri în firul de Fig.7.3. Dependenţa timpului mediu de răspuns d
aşteptare (fie t(τ)= τ – τs, aici τs fiind momentul sosirii timpul de servire în cazul disciplinelor FIFO şi
cererii), iar ts timpul de servire estimat. Pentru două cereri
cu acelaşi timp de aşteptare, prioritate are cererea mai
scurtă. În practică, priorităţile sunt recalculate în momente
discrete de timp şi firul de aşteptare este reordonat la
necesitate.
Ideea directoare a acestui algoritm este de a partaja echitabil procesorul, încercând să se
menţină o valoare constantă a raportului k = t/ts, unde t este timpul total de aflare a unei
cereri în sistem. Dacă aceasta se respectă, totul se va petrece pentru fiecare lucrare ca şi
cum ea ar dispune de un procesor de k ori mai slab (mai puţin rapid) decât procesorul real.
Disciplina HRN privilegiază lucrările scurte, însă penalizarea lucrărilor de lungă durată este
01.09.20
redusă de efectul priorităţii variabile. 20 247
Algoritmii descrişi mai jos vizează la fel partajarea echitabilă
12:47:15 a procesorului, dar nu necesită
ieşire
intrar
e
f_eligibil proc_ale
s
Fig.7.4. Alocarea procesorului: metoda
caruselului
Caruselul este un exemplu de disciplină cu retragere. Ea poate fi considerată o aproximare a
disciplinei “cel mai scurt primul” pentru cazul când durata execuţiei lucrărilor nu este
cunoscută anticipat. Este utilizată în sistemele interactive; valoarea cuantei este aleasă
astfel ca majoritatea cererilor interactive să poată 01.09.20
fi executate în timpul unei cuante.
Evident, valoarea cuantei trebuie să fie net mai mare decât 20 durata
12:47:15
comutării procesorului.
248
Analiza este mai simplă (τ →0, timpul de comutare a procesorului neglijat)
- procesor partajat (PP), totul are loc ca şi cum fiecare proces dispune imediat de
un procesor viteza de procesare a căruia este cea a procesorului real, divizată la
numărul curent al proceselor servite:
ta(ts) = ρts/(1-ρ),
iar timpul de răspuns este
t(ts) = ts/(1-ρ).
Acest model conţine n fire de aşteptare F0, F1,..., Fn-1. Fiecărui fir Fi îi este asociată o
cuantă proprie τi, valoarea căreia creşte odată cu i. O lucrare din Fi este servită
doar dacă firele de număr inferior lui i sunt vide.
Dacă o lucrare din Fi şi-a epuizat cuanta sa fără a se termina, ea intră în firul Fi+1;
lucrările din Fn-1 se întorc tot aici. Lucrările noi intră în F (fig. 7.5).
01.09.20 0
20 249
12:47:15
t(ts) t(ts)
CM PP CM
PP
CSSP
CSSP
ts ts
FIFO – prim sosit prim servit PP – procesor partajat
intrare procesor ieşire CSSP – cerere scurtă servită prima CM – carusel
multinivel
Fig. 7.5. Carusel cu mai multe niveluri Fig. 7.6. Compararea disciplinelor de alocare a procesorului
01.09.20
20 250
12:47:15
7.3. Tratarea blocărilor
O atare situaţie poate fi generalizată pentru un număr oarecare de procese şi resurse, dacă sunt
îndeplinite următoarele condiţii:
1) resursele sunt utilizate în excludere mutuală,
2) fiecare proces trebuie să utilizeze simultan mai multe resurse, şi acaparează fiecare
resursă pe măsura necesităţilor sale, fără a le elibera pe cele pe care le posedă deja,
3) cererile de resurse sunt blocante şi resursele nu pot fi retrase,
4) există o mulţime de procese {p0,..., pn}, astfel încât p0 cere o resursă ocupată de p1, p1 cere
o resursă ocupată de p2, ..., pn cere o resursă ocupată de p0.
01.09.20
20 251
12:47:15
8. ADMINISTRAREA MEMORIEI 8.5. Principiile şi mecanismele de bază ale
paginaţiei
8.1. Concepte de bază
8.5.1. Paginarea unei memorii liniare
8.1.1. Memorie virtuală
8.5.2. Paginarea unei memorii segmentate
8.1.2. Probleme de alocare a memoriei
8.5.3. Implementarea paginării
8.1.3. Alocarea dinamică a memoriei
8.6. Gestiunea memoriei virtuale paginate
8.2. Comportamentul programului
8.6.1. Parametrii unei discipline de alocare
8.2.1. Comportamentul într-o memorie
virtuală liniară 8.6.2. Algoritmi de reamplsare cu partiţie fixă
8.2.2. Comportamentul programelor 8.6.3. Algoritmi cu partiţie variabilă. Reglarea
segmentate şarjei
8.3. Partiţionarea memoriei fără 8.7. Gestiunea unei memorii cu mai multe
reamplasare nivele ierarhice
8.3.1. Metoda du-te – vino simplă 8.7.1. Memorii ierarhice
8.3.2. Partiţionarea memoriei 8.7.2. Administrarea transferurilor
8.4. Alocarea dinamică a zonelor de 8.8. Resurse tehnice de administrare a
memorie memoriei în procesoarele Intel
8.4.1. Mecanisme de reamplasare
dinamică
8.4.2. Algoritmi de alocare
Separarea conceptuală a problemelor de desemnare şi de legare, pe de o parte, şi a problemelor
de alocare a memoriei, pe de alta, este prezentată schematic mai jos.
1) Memoria virtuală liniară sau plată. Memoria virtuală este o suită de amplasamente identice,
organizate secvenţial şi desemnate de valori întregi consecutive, numite adrese virtuale.
Un obiect este reprezentat de una sau mai multe locaţiuni consecutive şi este desemnat de
adresa virtuală a primului amplasament.
Alocarea memoriei trebuie să permită unui proces să acceseze un obiect definit în memoria
virtuală, aducând în timp acceptabil acest obiect în memoria principală, unica care este
direct adresabilă. Ca rezultat, o disciplină de alocare a memoriei trebuie să soluţioneze
următoarelor două probleme:
a) stabilirea corespondenţei între adresele virtuale şi adresele fizice,
b) realizarea gestiunii memoriei fizice (alocarea locaţiunilor, transferul informaţiilor).
Dacă informaţiile aparţin mai multor utilizatori apar două restricţii suplimentare:
c) realizarea partajării informaţiilor între mai mulţi utilizatori,
d) asigurarea protecţiei reciproce a informaţiilor, care aparţin unor utilizatori distincţi.
Exemplul 8.1. Reacoperire (overlay). În acest exemplu:
memoria fizică
programul
arbore de
reacoperire
configuraţia 1
configuraţia 2
Fig.8.1. Execuţie cu reacoperire
Scopul unei discipline de alocare dinamică a memoriei este să asigure, că la orice instanţă de
timp informaţia necesară pentru execuţia instrucţiunii curente este accesibilă procesorului
imediat, adică se află în memoria principală. O disciplină de alocare trebuie să specifice
următoarele momente:
Când va fi încărcat un obiect în memoria principală?
atunci când este necesar (încărcare la cerere),
înainte de a fi necesar (preîncărcare).
Unde va fi încărcat acest obiect?
dacă există spaţiu liber suficient, în care amplasamente (problema amplasării),
în caz contrar, care obiecte să fie întoarse în memoria secundară (problema reamplasării).
Considerăm un program, executat într-o memorie virtuală liniară, care conţine toate
instrucţiunile şi datele. Precizări:
Trecerea timpului este reperată prin execuţia unor instrucţiuni consecutive: executarea unei
instrucţiuni defineşte o unitate de timp. Acest timp se numeşte virtual, deoarece el este
asociat unei execuţii fictive a programului în ipoteza că el dispune de toate resursele
necesare (memorie şi procesor). În cazul partajării resurselor, putem considera că
programele sunt independente.
Cererea de memorie este evaluată împărţind memoria virtuală în pagini adiacente de lungime
fixă, care conţin un număr întreg np de amplasamente. Accesarea unui amplasament dintr-
un bloc se numeşte referire a acestui bloc. Blocurile sunt numerotate cu valori întregi
consecutive, care permit etichetarea referinţelor. Modificând valoarea lui np, putem
examina comportamentul programului la diferite nivele de detaliere. La nivelul cel mai fin
(np=1) putem urmări referinţele instrucţiune cu instrucţiune.
Această secvenţă este numită lanţ de referinţe pentru programul considerat şi lungimea aleasă a
paginii.
01.09.20
20 256
12:47:15
8.2.1.1. Proprietăţile lanţurilor de referinţe
Experienţa arată, că lanţurile de referinţe posedă caracteristici comune, care pot fi descrise
calitativ astfel:
Neuniformitate. Fie ni numărul total de referinţe la pagina pi. Repartiţia valorilor ni este
neuniformă: o parte mică a paginilor totalizează o parte importantă a numărului total de
referinţe. Pentru exemplificare: se constată frecvent că un număr de peste 75% de
referinţe sunt generate de mai puţin de 25% de pagini.
Această ultimă proprietate poate fi exprimată într-un mod mai precis cu ajutorul unui model al
comportamentului programelor. În acest model, care este doar o reprezentare simplificată
a realităţii, derularea unui program este definită ca o succesiune de “faze”, separate de
“tranziţii”. O fază i este caracterizată printr-o mulţime de pagini Si şi un interval de timp
(virtual) Ti. Când programul intră în faza i, el rămâne aici o perioadă de timp Ti şi
concentrează referinţele sale la paginile care aparţin lui Si. Apoi are loc o tranziţie, în cursul
căreia referinţele la pagini sunt dispersate, înaintea intrării în faza i+1.
Fazele constituie, deci, perioade de comportament stabil şi relativ previzibil, în timp ce tranziţiile
au un comportament mai greu de stăpânit. 01.09.20
20 257
12:47:15
Noţiunea de mulţime de lucru (“working set”)
este utilizată în egală măsură pentru
caracterizarea comportamentului unor
programe, cât şi pentru a încerca să
prognozăm acest comportament după
observări.
La orice moment de timp t, mulţimea de lucru
a ferestrei T, notată prin W(t,T), este mulţimea
paginilor, care au fost obiectul a unei referinţe
cel puţin în perioada t-T şi t (timp virtual).
Proprietatea de localizare este exprimată prin
faptul, că paginile care aparţin la W(t, T) au o
probabilitate mai ridicată, în comparaţie cu
alte pagini, să fie obiectul unei viitoare
referinţe la momentul de timp t, cu condiţia că
lungimea T a ferestrei este aleasă corect.
01.09.20
20 258
12:47:15
Intervalul între
două absenţe de
pagini
capacitatea memoriei
01.09.20
20 259
Fig.8.3. Intervalul mediu între două absenţe de
12:47:15
pagini în funcţie de capacitatea memoriei
8.3.2. Partiţionarea memoriei
8.3.2.1. Partiţionarea fixă
Într-un sistem cu partiţionare fixă memoria este împărţită în mod static într-un număr fix de
zone. Capacitatea şi limitele acestor zone sunt definite la generarea sistemului.
Fiecare program poate ocupa doar un singur segment şi este asociat în mod constant unei zone
de memorie. Programele sunt păstrate pe disc în cod absolut, iar adresele prezente în
fiecare program sunt adresele fizice, care corespund adreselor de implantare din zona
atribuită
sistemul zona 1 zona 2
memoria
fizică
A
C B
programe
1) Alocarea memoriei
2) Cronograma
Fig.8.6.activităţilor
Sistem cu partiţii fixe 01.09.20
Atunci când un program este transferat din sau spre zona sa,
260un
alt program dintr-o altă zonă
20
12:47:15
poate fi executat; bineînţeles este necesar un procesor de intrare-ieşire autonom (canal
sau ADM).
8.3.2.2. Partiţionarea variabilă
01.09.20
20 261
12:47:15
8.4.1. Mecanisme de reamplasare dinamică
Alocarea dinamică a memoriei, divizate în zone de capacităţi oarecare cere utilizarea unor
mecanisme de reamplasare dinamică a acestor zone:
Registre de bază. Amplasarea în memoria fizică a unui singur segment este definită de o
pereche de registre, numite registrul de bază şi registrul limită. Registrul de bază RB
conţine adresa fizică a originii segmentului; registrul limită RL joacă rol de protecţie,
interzicând accesul accidental la locaţiuni în afara segmentului. Pentru o adresă virtuală
(RB, RL, d), la fiecare accesare este efectuat următorul calcul al adresei:
a := RB+d;
if a ≤ RL then
adr.fiz.:= a
else
<eroare> - deviere tratată de sistem
endif
01.09.20
20 262
12:47:15
Segmentare.
Segmentarea poate fi considerată o extensie a adresării cu ajutorul registrelor de bază, care
evită problemele realocării acestor registre, atunci când este necesară schimbarea
segmentului. Fiecărui segment îi este asociat un descriptor, care conţine printre altele,
adresa sa de origine şi capacitatea; descriptorii sunt aranjaţi într-un tabel, desemnat de un
registru special. Calculul adresei fizice corespunzătoare adresei segmentate (s, d) este
următorul:
desc := tab_desc[s];
if d < desc.capacitate then
adr.fiz.:= desc.orig+d
else
<eroare> - deviere tratată de sistem
endif
Orice accesare a memoriei cere o accesare suplimentară pentru citirea descriptorului. Pentru
sporirea eficienţei acceselor este folosit un dispozitiv de accelerare, constituit dintr-o
memorie asociativă de capacitate mică (de obicei, cu 8 sau 16 intrări), în care sunt păstraţi
descriptorii segmentelor la care au fost făcute cele mai recente referinţe, numerele acestor
segmente servesc drept chei de referinţă. La o accesare a memoriei, descriptorul
segmentului este căutat mai întâi în memoria asociativă, tabelul segmentelor fiind
consultat doar în cazul unui eşec.
Algoritmii sunt clasificaţi conform modului de reprezentare a zonelor libere. Cel mai frecvent
sunt utilizate următoarele trei metode:
• Înlănţuirea zonelor libere într-o listă,
• Divizarea blocurilor (“buddy systems”),
• Zone de capacităţi predefinite.
01.09.20
20 264
12:47:15
Zone libere înlănţuite
Ajustarea cea mai bună (“best fit”). Se va alege zona z, care va minimiza valoarea reziduului
(zona care rămâne liberă după alocare); altfel, vom alege z pentru care capacitate(z) – t
este minimă, ceea ce impune parcurgerea întregii liste sau ordonarea listei conform
capacităţilor zonelor. Scopul urmărit în acest caz este ameliorarea utilizării globale a
memoriei, existând pericolul apariţiei unor zone mici, puţin utilizabile.
01.09.20
Reziduul cel mai mare (“worst fit”). Va fi aleasă zona z pentru care
20
12:47:15
capacitate(z)
265 – t este
maximă. Se încearcă în acest mod să se lupte cu problemele metodei precedente.
În toate cazurile, un bloc de capacitatea t este amplasat în zona z; reziduul, dacă
există, înlocuieşte zona iniţială şi descriptorii sunt actualizaţi. În scopul diminuării
numărului total de zone adesea este fixată o limită inferioară a capacităţii
reziduului.
Atunci când o zonă este eliberată, ea este reinserată în listă şi fuzionată, dacă există
spaţiu, cu zona sau zonele vecine. Această fuzionare este facilitată, dacă zonele
sunt dublu înlănţuite şi ordonate în ordinea de creştere a adreselor.
Cercetările numeroase, efectuate asupra acestor algoritmi arată, că alegerea între “first
fit” şi “best fit” depinde de caracteristicile cererii, “first fit” fiind mai rapid, dacă
dispersia capacităţilor cerute este mare, rata de utilizare a memoriei fiind
aproximativ aceeaşi.
01.09.20
20 266
12:47:15
Alocare prin divizare (“buddy systems”)
În metoda alocării prin divizare capacităţile zonelor sunt cuantificate: ele sunt exprimate în
multiplii unei oarecare unităţi de alocare şi capacităţile permise sunt definite de o relaţie
de recurenţă. De obicei sunt utilizate două sisteme:
sistemul binar (1, 2, 4, 8,...), Si+1 = 2Si,
Fibonacci (1, 2, 3, 5, 13,...) Si+1 = Si+ Si-1.
Atunci când caracteristicile cererilor sunt bine cunoscute şi marea majoritate a cererilor vizează
o mulţime de capacitate bine definită, este recomandat un algoritm ad-hoc.
De exemplu, măsurările efectuate pentru sistemul IBM VM/370 au arătat că aproximativ 95%
din cereri aparţin unei mulţimi de 10 lungimi particulare. Alocatorul utilizează 10 zone,
fiecare având una din lungimi, evitându-se astfel parcurgerea înlănţuirilor pentru
majoritatea cazurilor.
Un algoritm “first fit” tratează cazul cererilor diferite de cele 10 cereri tip. Memoria este periodic
reorganizată pentru realimentarea zonelor.
Pentru orice algoritm, mai devreme sau mai târziu spaţiul liber poate deveni insuficient. Pot fi
recomandate mai multe remedii:
Dacă unele din blocurile alocate au devenit inaccesibile, acestea vor fi recuperate prin tehnici
speciale de “înlăturare a fărămiturilor”.
01.09.20
20 268
12:47:15
8.4.2.2. Utilizarea algoritmilor de alocare
Unele sisteme (de exemplu, CDC, Univac) la terminarea fiecărei lucrări efectuau o
defragmentare a memoriei pentru a păstra un spaţiu liber unic; imaginile registrelor bază-
limită sau tabelul segmentelor trebuie reînnoite pentru lucrările deplasate (fig.8.10).
liber
liber
Liber
Lucrări
Sistem Sistem
rezident rezident
Bază Limită
după terminarea T2
Limitele metodei alocării pe zone rezultă din restricţia contiguităţii zonelor alocate.
Drept rezultat, amplasamentele libere nu sunt resurse banalizate deoarece, un
segment logic nu poate fi încărcat în două zone libere, care nu sunt vecine chiar
dacă spaţiul total este suficient. Reorganizarea memoriei rămâne o operaţie prea
costisitoare pentru a putea fi practicată frecvent.
01.09.20
20 271
12:47:15
8.5. Principiile şi mecanismele de bază ale paginaţiei
O memorie virtuală paginată este divizată în blocuri de lungime fixă, sau pagini, care servesc
drept unităţi de alocare. Memoria fizică la fel este divizată în blocuri de aceeaşi lungime,
numite pagini de memorie fizică. Vom prezenta mai jos mecanismele de paginaţie a unei
memorii virtuale liniare şi a unei memorii virtuale segmentate.
Etapa a) impune să avem pentru fiecare memorie virtuală o descriere a implantării. Forma cea
mai simplă a descrierii este un tabel care indică adresa în memoria secundară a fiecărei
pagini virtuale. O memorie segmentată conţine un astfel de tabel pentru fiecare segment.
O altă posibilitate de descriere combină memoria virtuală şi fişierele: unei zone a memoriei
virtuale i se asociază conţinutul unuia sau a mai multor fişiere. Localizarea unei pagini
virtuale în memoria secundară este, în acest caz determinată consultând tabelul de
implantare a fişierului.
Partajarea informaţiilor între mai multe memorii virtuale generează apariţia următoarelor trei
probleme:
• notarea: cum vor fi adresate într-un mod uniform informaţiile partajate,
• partajarea fizică: cum să se garanteze că informaţiile partajate există într-un singur exemplar,
• protecţia: cum să se garanteze respectarea regulilor de acces la informaţiile partajate.
În cazul unei memorii virtuale liniare numele unui obiect este adresa sa virtuală. Pot fi două
cazuri distincte, în dependenţă de prezenţa sau lipsa unui mecanism de reamplasare în
memoria virtuală.
• Dacă da (cazul unei memorii virtuale cu registre de bază), un obiect partajat poate
fi amplasat la adrese diferite pentru fiecare memorie virtuală, deoarece registrele
de bază sunt proprii fiecărei memorii.
• Dacă nu (cazul cel mai frecvent), încărcarea unui obiect partajat fixează în mod
definitiv amplasarea sa, care trebuie să fie aceeaşi în toate memoriile virtuale. Este
necesar, deci, să fie rezervate în fiecare memorie virtuală adrese fixe, definite prin
convenţie pentru fiecare obiect partajat. Acesta 01.09.20
este cazul componentelor
sistemului de operare, partajate de către toţi utilizatorii.
20
12:47:15
277
Protecţia informaţiilor partajate
Dacă unitatea de partajare este pagina, unei pagini partajate îi pot fi atribuite drepturi de
acces distincte pentru fiecare memorie virtuală în care aceasta figurează. Aceste
drepturi sunt specificate la intrarea respectivă a fiecărui tabel de pagini.
Dacă unitatea de partajare este segmentul, protecţia selectivă este aplicată întregului
segment. Drepturile de accesare a unui segment de către un proces figurează în tabelul
de segmente ale procesului.
Dacă sunt specificate drepturi individuale de accesare a paginilor segmentului, acestea sunt
prezente în tabelul de pagini partajate de către procesele utilizatoare şi sunt, deci,
partajate de către toate aceste procese. Ele trebuie să fie în acest caz compatibile cu
drepturile globale, asociate segmentului.
01.09.20
20 278
12:47:15
Gestiunea memoriei virtuale paginate
Parametrii unei discipline de alocare
Disciplinele de alocare a unei memorii paginate pot fi clasificate în conformitate cu mai multe
criterii. Vom presupune că sistemul este multiprogramat, fiecare dintre procese
posedând memorie virtuală proprie.
Este mai puţin costisitor să fie reamplasată o pagină, care nu a fost modificată în toată
perioada încărcării sale (pagină “curată”), decât una care a suferit modificări (pagină
“murdară”). O pagină curată posedă o copie în memoria secundară şi nu este necesar să
fie salvată. Indicatorul modif[p], întreţinut în mod automat, permite aplicarea acestui
criteriu.
2) Pagini partajate
În unele cazuri este de dorit să se acorde temporar unei pagini un statut special, care ar
proteja-o de înlocuire. Acesta este cazul paginilor utilizate ca bufere de intrare-ieşire pe
durata transferului.
01.09.20
20 280
12:47:15
Descrierea algoritmilor de reamplasare
Doi algoritmi, care descriu două cazuri extreme: algoritmul optimal, care presupune
cunoaşterea totală a viitorului comportament al programului şi algoritmul „neutru”, care
nu utilizează nici un fel de informaţii iniţiale.
Pentru un lanţ de referinţe dat poate fi arătat, că algoritmul următor minimizează numărul
total de pagini lipsă: atunci când o pagină este lipsă drept victimă va fi aleasă o pagină,
care nu va fi obiectul unei referinţe ulterioare sau, dacă nu este posibil, pagina care va fi
obiectul celei mai târzii referinţe. Acest algoritm presupune cunoaşterea mulţimii, care
formează lanţul de referinţe, din care motiv este irealizabil în timp real. Permite
evaluarea la limită a algoritmilor (cazul cel mai favorabil, strategia optimistă).
2) Alegere aleatoare
Victima este aleasă la întâmplare (repartiţie uniformă) dintre mulţimea paginilor, prezente în
memorie. Acest algoritm nu ţine cont de comportamentul observat sau previzibil al
programului (cazul cel mai puţin favorabil, strategia pesimistă).
01.09.20
20 281
12:47:15
Descrierea algoritmilor de reamplasare
Victimă este pagina care a fost încărcată cu cel mai mult timp în urmă. Principalul avantaj
este simplicitatea realizării: este suficient să se păstreze într-un fir „prim sosit – prim servit”
numerele paginilor fizice în care sunt încărcate paginile logice succesive.
Realizarea algoritmului impune ordonarea paginilor fizice conform timpului ultimei referiri a paginii pe care
le conţin. Pentru aceasta, fiecărei pagini fizice i se va asocia o informaţie, care va fi pusă la zi la fiecare
referire. Aceasta poate fi timpul când a avut loc referirea. Mai puţin costisitor poate fi utlizarea unui contor
al referirilor. Necesitatea de a pune periodic contoarele în zero (atunci când acestea ating capacitatea
01.09.20
maximă) a condus la faptul că această soluţie a fost utilizată doar pentru 20 instalaţii
282experimentale.
12:47:15
„Algoritmul celei de-a doua şanse” sau FINUFO („First In Not Used, First Out”)
Paginile fizice sunt ordonate într-un fir circular şi un pointer ptr indică ultima pagină fizică
încărcată. Algoritmul poate fi descris după cum urmează:
ptr := următorul(ptr);
while U[ptr] 0 do
U[ptr] = 0;
ptr := următorul(ptr);
endwhile;
victima := ptr;
Pointerul se deplasează până la prima pagină fizică cu bitul U zero, iar bitul U egal cu 1 al
paginilor întâlnite în drum este pus în 0.
Acest algoritm mai este numit algoritmul „ceasului” („Clock”), deplasarea pointerului fiind
asemănată cu cea a acelor de ceasornic.
Punerea în 1 a bitului U atunci când are loc o referire poate fi realizată cu ajutorul unui
mecanism hardware sau software. 01.09.20
20 283
12:47:15
Algoritmi cu partiţie variabilă. Reglarea şarjei
Rezultatele prezentate în continuare arată, că pare a fi preferabil să
se încerce alocarea unui volum de memorie bine adaptat
comportamentului fiecărui program.
01.09.20
20 287
12:47:15
Despre procesoarele i386
Procesorul i386 are două moduri de lucru:
• real - procesor 8086 accelerat, având un set de instrucţiuni de bază mai extins,
• protejat - poate utiliza toate mecanismele de organizare a memoriei pe 32 biţi, inclusiv mecanismele
de susţinere a memoriei virtuale şi mecanismele de comutare a lucrărilor. În afară de aceasta, în modul
protejat pentru fiecare lucrare procesorul i386 poate emula procesoarele 8086 şi 286, care se vor numi
în acest caz procesoare virtuale. În aşa fel, în regimul multitasking modul protejat procesorul i386
lucrează ca un set de procesoare virtuale cu memorie comună.
Regimul procesorului virtual i86, care este numit V86, susţine organizarea paginată a
memoriei şi multitaskingul. Din această cauză lucrările, care sunt executate în
modul V86 folosesc aceleaşi mijloace de protecţie reciprocă a lucrărilor şi a SO
de lucrările utilizatorului, ca şi lucrările, executate în mod protejat i386.
Comutarea procesorului i386 din modul real în protejat şi invers are loc prin simpla
executare a instrucţiunii MOV, care modifică bitul de mod în unul din registrele de
control ale procesorului.
Comutarea în modul V86 are loc analogic modificând valoarea unui indicator anume
într-un alt registru.
01.09.20
20 288
12:47:15
Despre procesoarele i386
Productivitate suficientă pentru elaborarea şi implementarea unor sisteme de calcul sofisticate.
În aceste sisteme problema principală constă în depistarea şi eliminarea în timp minim a
erorilor posibile, iar în cel mai pesimist caz – să se stabilească modalitatea de minimizare a
consecinţelor acestor erori. Sistemele de acest gen pot fi depanate în timp mai scurt, iar
fiabilitatea poate fi mai mare, atunci când sunt produse în serie şi procesorul impus să
controleze fiecare instrucţiune dacă respectă criteriului de protecţie.
Criteriul de protecţie utilizat depinde de aplicaţia concretă. Sistemele mai simple, de timp real,
de exemplu, în care toate momentele pot fi cercetate la etapa de elaborare şi
implementare, au un comportament relativ corect şi fără utilizarea mecanismelor speciale
de protecţie. Însă în condiţii de incertitudine, în lipsa unor informaţii preliminare, datorate
contextului aleator al domeniului, utilizarea mecanismelor speciale de protecţie este
obligatorie.
Procesoarele i386 permit soluţionarea acestor probleme prin:
• Partiţionarea spaţiilor de adrese ale aplicaţiilor,
• Utilizarea unor nivele de priorităţi (inele de protecţie, de la 0 la 3),
• Utilizarea unor instrucţiuni privilegiate,
• Clasificarea segmentelor pe tipuri (de exemplu, segmente de cod, segmente de date),
• Folosirea noţiunii de drepturi de acces la segmente şi pagini (RO, EO),
• Controlul graniţei unui segment.
Pentru păstrarea productivităţii maxime toate controalele protecţiei
01.09.20 sunt îndeplinite la executarea
20 289
unei instrucţiuni. 12:47:15
Mijloacele de susţinere a segmentării memoriei
Spaţiul fizic de adrese a procesorului i386 este de 4 Go (magistrala de adrese pe 32 de biţi).
Memoria fizică este liniară cu adrese de la 00000000 până la FFFFFFFF în cod hexazecimal.
Adresa virtuală, utilizată în program este reprezentată de perechea (nr. seg., depl). Deplasarea
este dată de câmpul respectiv al instrucţiunii, iar numărul segmentului – în unul din cele 6
registre de segment ale procesorului (CS, SS, DS, ES, FS şi GS), fiecare fiind de 16 biţi.
Mijloacele de segmentare formează nivelul superior al dispozitivului de administrare a memoriei
virtuale, iar dispozitivele de organizare a paginaţiei – nivelul inferior. Mijloacele de paginaţie
pot fi active sau dezactivate şi în dependenţă de aceasta se modifică sensul transformării
adresei virtuale, executate de mijloacele de segmentaţie.
Memoria virtuală segmentată este recomandată pentru sisteme nu prea mari pe 16 biţi în care
capacitatea segmentului nu este mai mare de 64 Ko. Pot fi utilizate segmente de 4 Go,
ceea ce dă posibilitatea organizării paginării acestora. Productivitatea înaltă în
administrarea memoriei virtuale este asigurată de folosirea unei memorii cash interne
pentru păstrarea informaţiilor virtual-fizic - tamponul de localizare a translatării, TLB -
conţine informaţii despre adresele a 32 de pagini, cel mai recent utilizate. Paginile memoriei
virtuale au capacitatea de 4 Ko, ceea ce înseamnă că TLB conţine la fiecare moment de
timp informaţii despre 128 Ko, permiţând cristalului transformarea adresei virtuale în
adresa fizică fără accesarea tabelului de pagini (98 - 99% cazuri de succes).
01.09.20
20 290
12:47:15
Dispozitivele de segmentare cu mijloacele de paginaţie dezactivate
01.09.20
20 296
12:47:15
Această schemă poate fi generalizată: dacă vom admite că o maşină poate utiliza
primitive furnizate de orice maşină de nivel inferior vom obţine schema (b), iar dacă
unica restricţie impusă grafului de dependenţă este lipsa circuitelor - schema (c).
În practică, metoda conceptului de descendenţă nu este niciodată utilizată în mod
absolut: procesele conţin iteraţii, iar la definiţia unor maşini noi se va ţine cont de
experienţa celui care o elaborează ca şi de existenţa maşinilor deja realizate.
Rezultat: este imposibil de propus apriori specificaţii detaliate ale interfeţei:
elaborarea specificaţiilor finale se bazează pe experimentări cu prototipurile lor.
Indiferent de maniera prin care se ajunge la noţiunea de structură ierarhică,
aceasta prezintă o serie de avantaje:
•Independenţa conceperii: comportamentul unei maşini, pentru utilizatorii săi, este
totalmente descris de specificările interfeţei sale.
•Independenţa modificării: modificările unei maşini nu generează modificări pentru
maşinile care o utilizează, dacă specificările interfeţei rămân neschimbate.
•Independenţa realizării: interfaţa odată specificată, o maşină M poate fi realizată
independent de cele care o utilizează şi invers, interfaţa lui M fiind corect realizată,
maşinile care utilizează maşina M pot fi puse la punct independent
01.09.20
20 297
de M.
12:47:15
Noţiunea de obiect
Decompoziţia ierarhică în maşini abstracte nu acoperă toate aspectele structurării
sistemelor. În particular, pot apărea probleme atunci când unele situaţii sau
elemente trebuiesc create ori distruse în mod dinamic, sau când vrem să descriem
elemente, care posedă proprietăţi comune.
Pentru a facilita luarea în consideraţie a acestor aspecte este introdus instrumentul
de structurare obiect.
Un obiect este definit cu ajutorul următoarelor atribute:
• un nume, care permite desemnarea obiectului şi deosebirea lui de alte obiecte,
• o stare, care este definită în orice moment de timp şi poate evolua pe parcursul
timpului,
• o mulţime de operaţii, funcţii de acces sau metode, care permit:
- crearea şi distrugerea obiectelor,
- consultarea şi modificarea stării unui obiect,
- combinarea obiectelor.
Clasa permite gruparea obiectelor cu proprietăţi comune, fiind un instrument al
abstractizării. Unei clase îi sunt ataşate o mulţime de funcţii de acces (metode),
aplicabile tuturor reprezentanţilor clasei; fiecare obiect al clasei posedă un nume şi
o stare proprie. Orice obiect aparţine unei clase; atunci când un obiect este creat,
se va specifica numele şi starea sa iniţială; metodele asociate clasei sale sunt în
mod automat moştenite. Un obiect, odată creat, poate fi accesat cu ajutorul
01.09.20
funcţiilor de acces specificate de clasă. Programele acestor 20 funcţii
298 sunt, de obicei,
12:47:15
partajate între toate obiectele clasei, însă fiecare obiect mai conţine şi date proprii.
Interfeţe şi specificări
O interfaţă este asociată unei maşini abstracte sau unei clase de obiecte. Ea
conţine doar trei tipuri de informaţii, accesibile utilizatorului maşinii sau obiectului:
- structuri de date,
- proceduri (metode),
- o mulţime de reguli de utilizare a datelor şi a procedurilor.
Regulile de utilizare constituie un mod de întrebuinţare a structurilor de date şi
procedurilor. Ele exprimă restricţiile utilizării lor, şi pot lua diverse forme:
- restricţii de accesare a datelor (numai citire, de exemplu),
- restricţii, legate de ordinea de execuţie a procedurilor,
- restricţii, care afectează execuţia simultană a procedurilor sau accesarea
simultană a datelor.
Problema formulării specificărilor unei interfeţe nu are încă o soluţie generală
satisfăcătoare. Doar o parte a specificărilor poate fi exprimată in mod formal şi
există posibilitatea unor validări automate: acestea sunt specificările tipurilor
variabilelor şi a parametrilor procedurilor.
300
01.09.2020 12:47:15
Limbajul de comandă
Sistemul trebuie să permită:
- salvarea şi păstrarea informaţiilor în fişiere pe dischetă,
- transferarea informaţiilor între fişiere şi periferice,
- elaborarea, depanarea, salvarea şi executarea programelor.
Structura SO va permite adaptarea simplă la diferite configuraţii de calculatoare,
în special, la diferite tipuri de memorie secundară şi echipamente periferice.
Interfaţa utilizatorului, oferită de către sistemul de operare, este definită de un
limbaj de comandă specificat astfel:
<comandă> ::=<nume comandă><listă parametri>
<listă parametri> ::=spaţiu|<listă parametri><parametru>
<parametru> ::=<nume fişier>
O comandă este introdusă de la tastatură şi executată imediat.
Un fişier este un set de informaţii desemnate printr-un nume şi manipulate cu
ajutorul unor funcţii de acces. Fişierele sunt păstrate în memoria secundară.
Programele şi datele utilizatorului se află în fişiere.
01.09.20
20 301
12:47:15
Comenzi predefinite
Un oarecare număr de comenzi de bază sunt predefinite în sistem. Orice program executabil,
creat de utilizator sub formă de fişier poate fi executat ca şi o comandă:
<nume comandă>::=<nume comandă predefinită>|<nume fişier executabil>
Cu titlu de exemplu, o listă de comenzi pentru crearea şi depanarea în limbajul de asamblare:
1) editare fsursă -- editarea programului sursă
să se asigure posibilitatea modificării unui fişier fsursă care conţine textul programului (sau să
se asigure posibilitatea creării lui, dacă acesta nu există) cu ajutorul unor comenzi interne,
definite de un editor interactiv, furnizat de sistem, detaliile de funcţionare ale căruia nu sunt
specificate aici.
2) asamblare fsursă fobiect -- asamblare
să se asambleze programul din fsursă şi să se plaseze codul obiect în fobiect.
3) fobiect fdate frezultat -- executare
să se execute programul conţinut în fişierul fobiect citind datele din fişierul fdate pasând
rezultatele în fişierul frezultat.
4) depanare -- depanare interactivă
01.09.20
20 302
12:47:15
9.2.1.2. Decompoziţia sistemului. Interfeţe interne
O primă versiune a SO poate fi realizată utilizând direct interfaţa definită de maşina fizică.
Vom arăta mai jos modul în care un sistem fizic monolit poate fi pas cu pas descompus
pentru a ajunge la subansambluri logic coerente.
Gestionarea fişierelor şi a fluxurilor
Izolăm componenta sistemului responsabilă de administrarea fişierelor. Pentru aceasta trebuie
să precizăm structura fişierelor şi să specificăm funcţiile de acces.
Presupunem că un fişier este organizat sub forma unei secvenţe de înregistrări de lungime
fixă. Citirea şi scrierea se va face în mod secvenţial: pentru fiecare fişier f este definit un
pointer ptr(f) de citire/scriere, o variabilă booleană sfr(f) şi un mod de acces (numai citire sau
citire/scriere). Funcţiile de acces sunt definite după cum urmează:
Primul octet al parametrului tampon al funcţiilor de mai sus specifică numărul de caractere din linia origine
sau destinaţie, care vor fi transferate.
Noţiunea de periferic logic mai este întâlnită sub denumirea de flux de intrare-ieşire.
01.09.20
20 306
12:47:15
2) Realizarea operaţiilor de intrare-ieşire
Realizarea maşinii SGF, care administrează fişierele şi fluxurile, poate de asemenea fi simplificată dacă
avem la dispoziţie primitive de intrare-ieşire mai evoluate decât cele furnizate direct de maşina fizică.
Vom defini o nouă maşină, numită PIE (primitive intrări-ieşiri), cu următoarea interfaţă:
a) Schimburi cu discul. Un disc este organizat în piste şi sectoare, sectorul este unitatea de transfer,
iar o adresă de disc are forma (nr. suport, nr. pistă, nr. sector).
b) Schimburi cu alte periferice. Unitatea de transfer este un caracter. Vor fi definite trei funcţii:
citire_car(c) : citeşte un caracter de la tastatură (rezultatul c)
afişare_car(c) : afişază un caracter pe display (originea c)
imprimare_car(c) : imprimă un caracter la imprimantă (originea c)
Pentru a permite utilizarea asistată de SGF a acestor funcţii, ele sunt definite pentru periferice logice.
Accesarea perifericelor fizice este realizată printr-o simplă redirecţionare via un tabel de corespondenţă.
01.09.20
20 307
12:47:15
SO pe trei nivele
Această remarcă evidenţiază importanţa alegerii interfeţelor în cauză. De exemplu, interfaţa PIE trebuie să
permită simplificarea realizării maşinilor care o utilizează, rămânând ea însăşi relativ simplu de
realizat, ceea ce poate fi obţinut doar în mod iterativ, făcând în egală măsură apel la experienţă. În
cursul acestui proces iterativ interfeţele principale sunt elaborate progresiv până la varianta stabilă.
Costul modificaţiei unei interfeţe creşte odată cu creşterea numărului componentelor care o utilizează
şi este, ca rezultat, mai ridicat pentru interfeţele principale ale sistemului.
01.09.20
Interfaţa externă a sistemului, care este cea a ILC, este definită de limbajul
20 de 308
comandă. Interfeţele
interne (ale PIE şi SGF) sunt realizate prin apelări ale supervizorului.
12:47:15
9.2.2. Primitive de intrare-ieşire
Driverele dispozitivelor periferice urmează schema sincronă (v. 2.4.2.1). Vom descrie mai întâi
administrarea unei unităţi de disc, apoi intrările-ieşirile în mod caracter.
Exemplul care urmează este pentru un disc cu un format particular, dischetă simplă densitate cu o singură
suprafaţă de lucru. Parametrizarea pentru formatare va fi examinată mai târziu. Discheta are 77 piste
de 27 sectoare; lungimea sectorului - 128 octeţi. Sectorul este unitatea de transfer a informaţiei.
Pentru accelerarea transferurilor secvenţiale acestea sunt realizate printr-o zonă de memorie-tampon. La o
operaţie de citire este recomandat să se citească o pistă întreagă, deoarece întârzierea introdusă de
căutarea pistei intervine o singură dată pentru toată mulţimea sectoarelor. Din această cauză vor fi
rezervate în permanenţă n zone-tampon de lungimea unei piste (27 sectoare de 128 caractere).
Valoarea lui n de ordinul câtorva unităţi va fi fixată la generarea sistemului.
Fie că este necesar să se citească un sector cu numărul nsect de pe pista np. Dacă unul din tampoane
conţine pista np, citirea se va face fără a accesa discheta, din sectorul respectiv al zonei-tampon. În
caz contrar, conţinutul pistei np va trebui încărcat în prealabil de pe dischetă în una din zonele-
tampon. Alegerea zonei-tampon va fi tratată mai departe.
01.09.20
20 309
12:47:15
Operaţia de scriere
Este mai complicată. Pentru a minimiza numărul de transferuri, un tampon este recopiat pe dischetă cât
mai târziu posibil. Atâta timp cât el este în memoria operativă, tamponul reflectă starea curentă a
sectoarelor pistei şi accesările succesive ale unui sector nu antrenează vre-o accesare a dischetei. Fie
că este necesar să scriem în sectorul nsect al pistei np:
- dacă pista np este prezentă într-un tampon, sectorul corespunzător este modificat şi operaţia se
termină aici, cu excepţia cazului "scriere imediată"**,
- dacă pista np nu este prezentă, ea trebuie în prealabil adusă într-un tampon pentru a ajunge la
situaţia din cazul precedent, cu excepţia situaţiei primei scrieri.
Un sector este copiat pe disc, în afara cazului de scriere imediată, în două situaţii:
- dacă tamponul este realocat pentru a încărca o nouă pistă în memorie, conform algoritmului de
realocare, care va fi prezentat mai jos,
- dacă tamponul este vidat în mod forţat din cauza închiderii unui fişier sau la cererea de eliminare a
unui volum.
Vom avea un singur tampon (n=1) de lungimea unei piste, căruia îi sunt asociaţi doi indicatori:
pistă_prezentă : numărul pistei încărcate în tampon (nil dacă este vid)
modif: are valoarea TRUE dacă conţinutul zonei-tampon a fost modificat.
Interfaţa furnizată de PIE pentru gestionarea dischetelor este compusă din procedurile
ALEGERE_SUPORT(sup), CITIRE_SECTOR(adr,nsect) şi SCRIERE_SECTOR(adr,nsect). Ultima procedură,
SCRIERE_SECTOR(adr,nsect), conţine parametrul mod, care poate lua valorile scriere_normală,
scriere_imediată şi scriere_prima.
Nu vom descrie aici procedura ALEGERE_SUPORT(sup), care este realizată de o funcţie a controlerului.
01.09.20
20 311
12:47:15
Schemele programelor
citire_sector(np,nsect,dest) scriere_sector(np,nsect,orig,mod)
if np <> p_p then if np<> p_p then
if modif then if modif then
transferare_pistă(p_p,tampon,scriere) transferare_pistă(p_p,tampon,scriere)
endif; endif;
transferare_pistă(np,tampon,citire) if mod=scriere_prima şi liber(np) then
endif; p_p=np
dest:=tampon[nsect] else
transferare_pistă(np,tampon,citire)
endif
endif
tampon[nsect]:=orig;
if mod=scriere_imediată then
transferare_sector(orig,np,nsect,scriere)
else
modif:=TRUE
endif
În cazul unei prime scrieri se presupune că este posibil să se determine cu ajutorul indicatorului liber(np), că
întreaga pistă np este alocată pentru prima dată.
Procedurile de mai sus utilizează două proceduri interne ale PIE: transferare_pistă şi transferare_sector, care
constituie driver-ul dischetei. 01.09.20
20 312
12:47:15
Transferare pistă
01.09.20
20 313
12:47:15
9.2.2.2. Introducere – extragere caractere
Schema sincronă de comandă, pe care o vom relua pentru cazul scrierii unui simbol. Pentru a permite
reasocierea perifericelor, adresa controlerului va fi specificată ca un parametru al driverului.
procedura ieşire_car(c,p); transmite caracterul c controlerului p
TEST(p);
if nonpreg then
<tratare eroare>
endif;
EXTRAGE(c,p);
test: TEST(p);
if err then
<tratare eroare>
endif;
if nonterm then
go to test
endif;
O procedură analogică intrare_car(c,p) este definită pentru citire.
Pentru realizarea schimburilor cu perifericele logice este definit un tabel de asociere cu trei intrări:
tabel_perif[tastatură]=adresa controlerului asociat tastaturii logice
tabel_perif[display]=adresa controlerului asociat ecranului logic
tabel_perif[imprimantă]=adresa controlerului asociat imprimantei logice.
Operaţiile pe perifericele logice vor fi realizate astfel:
afişare_car(c) =>ieşire_car(c,tabel_perif[display]) 01.09.20
imprimare_car(c) =>ieşire_car(c,tabel_perif[imprimantă]) 20 314
citire_car(c) =>intrare_car(c,tabel_perif[tastatură]) 12:47:15
9.2.3. Sistemul de gestiune a fişierelor
9.2.3.1. Organizarea logică
Pentru notarea unui fişier este utilizată o schemă pe două nivele, adică numele unui fişier este de forma
<nume suport>:<identificator>.<tip>
Numele suportului identifică suportul fizic al fişierului, adică unitatea de disc utilizată şi este definit, de
obicei, în mod implicit.
În interiorul unei dischete schema de desemnare este “plată”; identificatorul tipului specifică natura
fişierului (program translatabil, absolut, instrucţiuni, date, etc.).
Fişierele sunt organizate secvenţial, sub forma unei suite de înregistări de lungime fixă (128 octeţi).
Sistemul furnizează primitive de accesare secvenţială a înregistrărilor. Orice funcţie de acces trebuie să fie
construită plecând de le aceste primitive.
01.09.20
20 315
12:47:15
9.2.3.2. Organizarea fizică
În calitate de unitate de alocare sau bloc vom considera un set de 8 sectoare consecutive. Starea de
alocare a dischetei este descrisă cu ajutorul unui tabel de ocupare, care conţine câte un bit pentru
fiecare bloc (fie 250 biţi; în realitate un pic mai puţin, fiindcă primele două piste ale dischetei sunt
rezervate în permanenţă). Găsirea unui bloc liber se reduce la găsirea primului bit egal cu 0 în acest
tabel: numărul bitului este numărul blocului căutat.
Datele despre un fişier sunt grupate într-un descriptor care conţine următoarele informaţii:
- numele fişierului (<identificator>.<tip>),
- lungimea fişierului (numărul de înregistrări),
- numărul înregistrării viitoare la citire sau scriere,
- tabelul implantării fişierului.
Tabelul implantării fişierului constă din 16 octeţi, care conţin numerele blocurilor succesive în care fişierul
este implantat. Deci, pot fi utilizate pentru implantarea unui fişier 128 de sectoare, adică 16 Ko.
Fişierele de lungime mai mare, numite multisecţionate, pot fi implantate prin înlănţuirea a mai multor
descriptori, fiecare descriind un set de 16 unităţi de alocare, numit secţiune a fişierului. Numărul
maxim de secţiuni este 16, adică 256 Ko în total.
Pistele 0 şi 1, rezervate sistemului de operare, conţin, în particular, tabelul de ocupare a dischetei şi
programul de încărcare. Descriptorii tuturor fişierelor dischetei sunt ordonaţi într-o zonă rezervată,
începând cu pista cu numărul 2. Mulţimea acestor descriptori formează catalogul dischetei.
Pentru a facilita adaptarea sistemului la diferite tipuri de discuri, caracteristicile discurilor sunt grupate într-
un tabel, creat la generarea sistemului de operare şi descris 01.09.20
în 9.2.3.4; acest tabel este utilizat de
toate programele care trebuie să cunoască organizarea fizică a discurilor.
20 316
12:47:15
9.2.3.3. Operaţii cu fişierele
Deschiderea unui fişier cere încărcarea descriptorului acestuia într-o zonă a memoriei centrale, rezervată în
prealabil. Adresa acestui descriptor este transmisă ca parametru tuturor operaţiilor ulterioare asupra
fişierului.
La închiderea unui fişier deschis, descriptorul din memorie este recopiat pe disc şi locul lui este eliberat ca
şi zona de memorie, ocupată de fişierul propriu-zis. Dacă rămân înregistrări modificate ale fişierului
într-o zonă-tampon de I-E, ele la fel vor fi recopiate pe disc. Scrierea se face în mod imediat.
Crearea unui fişier constă în alocarea unui descriptor (pe disc) acestui fişier; iniţial fişierul este vid şi
tabelul său de implantare conţine doar zerouri.
La distrugerea unui fişier vor fi eliberate toate unităţile de alocare ocupate de fişier, ca şi amplasamentul
ocupat de către descriptorul acestuia. Catalogul şi tabelul de ocupare a discului sunt puşi la zi.
Vom descrie principiile de organizare a programelor de citire şi scriere secvenţială a unei înregistrări.
Programele de creare, distrugere, deschidere şi închidere a unui fişier sunt propuse ca exerciţii.
Presupunem că un fişier f este deschis. Notăm descriptorul în memorie a acestui fişier prin descr, care are
următoarele câmpuri:
- descr(f).ptr pointer de citire/scriere
- descr(f).sfr indicator de sfârşit de fişier
- descr(f).lng numărul de înregistrări ale fişierului
- descr(f).imp tabelul de implantare a fişierului
01.09.20
Admitem, pentru simplitate, că lungimea unui fişier este limitată la o singură
20 secţiune.
317
12:47:15
Schemele programelor de accesare
procedura avansare(f);
if descr(f).ptr=descr(f).lng-1 then
descr(f).sfr:=TRUE
else
descr(f).ptr:=descr(f).ptr+1
endif
procedura citire_secv(f,dest);
if descr(f).sfr then
<eroare> -- citire imposibilă, ne aflăm la sfârşitul fişierului
else
calculare(f,np,nsect); -- calcularea adresei pistă-sector
citire_sector(np,nsect,dest);
avansare(f);
endif
01.09.20
20 318
12:47:15
9.2.4. Interpretorul limbajului de comandă
9.2.4.1. Schema generală
Schema generală a interpretorului limbajului de comandă poate fi reprezentată printr-o buclă infinită:
iniţializare_sistem
ciclu
iniţializare_comandă
citire comandă
analizare comandă
if comandă corectă then
interpretare comandă:
preparare mediu de execuţie
lansare execuţie
else
diagnosticare eroare
endif
endciclu
Comanda este citită într-un tampon de memorie cu ajutorul terminalului logic: procedura cititre_linie.
Analiza comenzii: Primul câmp este numele comenzii, urmează parametrii transmişi programului
responsabil de interpretare. Dacă numele este unul din cele rezervate comenzilor de sistem
programul căreia este rezident, poate începe interpretarea. În caz contrar, fişierul care conţine
comanda trebuie în prealabil încărcat în memorie. Dacă este cazul unui program executabil al
utilizatorului, pregătit într-un fişier şi un astfel de fişier nu poate fi găsit, interpretorul va afişa un
mesaj de eroare şi va aştepta comanda următoare.
Secvenţa iniţializare_sistem reprezintă încărcarea iniţială şi poate fi01.09.20
declanşată de un buton de pornire sau
printr-un apel al supervizorului. 20 319
Secvenţa iniţializare_comandă pune sistemul în stare stabilă: toate tampoanele modificate sunt vidate pe
12:47:15
disc, toate fişierele sunt închise; interpretorul afişează un mesaj de invitaţie şi aşteaptă comanda.
9.2.4. Interpretorul limbajului de comandă
9.2.4.1. Schema generală
Schema generală a interpretorului limbajului de comandă poate fi reprezentată printr-o buclă infinită:
iniţializare_sistem
ciclu
iniţializare_comandă
citire comandă
analizare comandă
if comandă corectă then
interpretare comandă:
preparare mediu de execuţie
lansare execuţie
else
diagnosticare eroare
endif
endciclu
Comanda este citită într-un tampon de memorie cu ajutorul terminalului logic: procedura cititre_linie.
Analiza comenzii: Primul câmp este numele comenzii, urmează parametrii transmişi programului
responsabil de interpretare. Dacă numele este unul din cele rezervate comenzilor de sistem
programul căreia este rezident, poate începe interpretarea. În caz contrar, fişierul care conţine
comanda trebuie în prealabil încărcat în memorie. Dacă este cazul unui program executabil al
utilizatorului, pregătit într-un fişier şi un astfel de fişier nu poate fi găsit, interpretorul va afişa un
mesaj de eroare şi va aştepta comanda următoare.
Secvenţa iniţializare_sistem reprezintă încărcarea iniţială şi poate fi01.09.20
declanşată de un buton de pornire sau
printr-un apel al supervizorului. 20 320
Secvenţa iniţializare_comandă pune sistemul în stare stabilă: toate tampoanele modificate sunt vidate pe
12:47:15
disc, toate fişierele sunt închise; interpretorul afişează un mesaj de invitaţie şi aşteaptă comanda.
9.2.4.2. Mediul de execuţie
01.09.20
20 321
12:47:15
9.2.4.3. Încărcarea unui program
Operaţia de încărcare are drept efect pregătirea mediului. Ea urmează imediat operaţiei de analiză a
comenzii. Vom descrie această operaţie în cazul în care <nume comandă> este numele unui fişier,
care conţine un program executabil. Antetul unui asemenea fişier descrie conţinutul său: lungimea şi
poziţia în cadrul fişierului a segmentelor de cod şi de date, adresa de debut a execuţiei, adresele de
implantare a acestor segmente pentru un program absolut, informaţii de reimplantare pentru un
program translatabil. Încărcarea presupune următoarele:
1) Deschiderea fişierului <nume comandă> şi citirea antetului acestuia într-un tampon intern.
2) Determinarea dacă capacitatea memoriei disponibile permite încărcarea.
3) Crearea paginii de gardă în amplasamentul rezervat acestui efect.
4) Încărcarea segmentelor de cod şi de date în zonele indicate în antet; dacă are loc reimplantarea să se
adauge adreselor realocate deplasarea necesară; să se pună la zi informaţiile, care descriu memoria
disponibilă.
5) Iniţializarea stivei de execuţie şi plasarea în topul ei a unei adrese de retur în interpretorul limbajului
de comandă.
6) Punerea la zi a pointerilor paginii de gardă; ordonarea în tamponul situat în această pagină a “cozii
de comenzi”.
7) Deschiderea fişierelor (dacă există) numele cărora sunt specificate în comandă şi plasarea
descriptorilor acestora în pagina de gardă.
8) Executarea unei ramificaţii spre punctul de intrare a segmentului de cod.
Aceste operaţii sunt executate în mod slave, returul normal din programul executat în interpretorul
limbajului de comandă utilizează returul procedurii. Acest retur poate fi făcut şi prin apelarea
supervizorului sau ca şi consecinţă a unei devieri provocate de o eroare.
01.09.20
20 322
12:47:15
9.2.4.4. Tratarea erorilor de execuţie
Detectarea unei erori în cursul execuţiei provoacă un cod de eroare sau o deviere, chiar dacă ea a survenit
sau nu în cursul executării unei primitive realizate prin intermediul unui apel al supervizorului.
Pot fi evidenţiate două cazuri în dependenţă de gravitatea erorii:
- Eroare într-un program utilizator sau într-o componentă necritică a unui program de sistem, cum ar
fi interpretorul limbajului de comandă. Exemplu: operaţie aritmetică care nu poate fi executată,
memorie insuficientă pentru încărcarea unui program.
- Eroare în cursul unei operaţii critice, adică care pune în pericol integritatea datelor. Exemplu: eroare
irecuperabilă la un transfer pe disc.
Pentru oricare caz, principiul tratării unei erori constă în revenirea la o stare stabilă a sistemului din care
executarea poate reîncepe normal, reducând la minimum cantitatea de informaţii pierdute. O
clasificare conform acestui criteriu evidenţiază următoarele stări stabile:
1) Stare predecesoare executării instrucţiunii eronate,
2) Aşteptarea de către interpretor a unei comenzi,
3) Starea iniţială a sistemului.
Returul în starea 1) sau 2) corespunde tratării unei devieri într-un program utilizator. Această tratare poate
fi realizată într-un mod standard de sistem sau de un program de tratare, elaborat de utilizator.
Returul la starea 2), adesea numit “restartare la cald” (fr. reprise à chaud, eng. warm start), este
realizat de secvenţa iniţializare_comandă. Lucrul efectuat în cursul ultimei comenzi este, in genere,
pierdut, însă datele permanente (fişierele) sunt păstrate.
Revenirea la starea 3), adesea numită restartare rece (fr. reprise à froid, eng. cold start), este rezultatul
unei erori grave, care provoacă alterarea tabelelor interne ale sistemului sau a fişierelor pe disc.
Returul este realizat de secvenţa iniţializare_sistem. Pierderea01.09.20
de informaţii poate fi importantă (stare
incoerentă a unei dischete); există totuşi programe, care permit, în cazul unei
20
12:47:15
323 atare erori, restabilirea
totală sau parţială a conţinutului unui disc, folosind redundanţa informaţiilor.
5. Gestiunea informaţiei ..................................................................................................................................................... 2
5.1. Principiile gestiunii informaţiei ............................................................................................................................... 2
5.1.1. Definiţii generale .............................................................................................................................................. 2
5.1.2. Interpretarea numelor ....................................................................................................................................... 3
5.1.2.1. Construirea căii de acces ........................................................................................................................... 4
5.1.2.2. Structura reprezentărilor. Descriptori ........................................................................................................ 4
5.1.2.3. Contexte şi medii ....................................................................................................................................... 5
5.1.3. Legarea ............................................................................................................................................................. 6
5.1.4. Protecţia ............................................................................................................................................................ 7
5.1.4.1. Domenii şi drepturi de acces...................................................................................................................... 7
5.1.4.3. Problemele protecţiei ................................................................................................................................. 8
5.2. Desemnarea şi legarea fişierelor şi intrărilor-ieşirilor ............................................................................................. 9
5.2.1. Căi de acces la un fişier .................................................................................................................................... 9
5.2.2. Desemnarea externă a fişierelor. Cataloage .................................................................................................... 10
5.2.2.1. Introducere ............................................................................................................................................... 10
5.2.2.2. Organizarea arborescentă......................................................................................................................... 10
5.2.3. Legarea fişierelor cu fluxurile de intrare-ieşire .............................................................................................. 11
5.3. Legarea programelor şi datelor .............................................................................................................................. 12
5.3.1. Etapele de viaţă a unui program ..................................................................................................................... 12
5.3.2. Funcţionarea unui încărcător .......................................................................................................................... 13
5.3.3. Funcţionarea unui editor de legături ............................................................................................................... 14
5.3.3.1. Legarea prin substituţie ........................................................................................................................... 14
5.3.3.2. Legarea prin înlănţuire ............................................................................................................................. 17
5.4. Mecanisme de gestiune a obiectelor ...................................................................................................................... 17
5.4.1. Segmentarea ................................................................................................................................................... 17
5.5. Exerciţii la capitolul 5.................................................................................................................................... 19
Trecerea de la identificator la obiectul propriu-zis se realizează prin compunerea funcţiilor de acces D şi Ri, obţinând
calea de acces la un obiect.
a) nume nume
b) nume i nume j
c)
..
obiect i nume obiect j
..
.
În calculatoarele care permit adresarea imediată, o constantă poate fi reprezentată în instrucţiune.
Noţiunea de descriptor este larg folosită în sistemele de gestiune a fişierelor (v. 5.2 şi cap. 7). O altă utilizare este
realizarea mecanismului de adresare segmentată. Segmentarea este o tehnică elementară de structurare a softului. Putem
spune, că segmentul este un obiect compus, de lungime variabilă, reprezentarea în memorie a căruia ocupă o suită de
amplasamente consecutive; el permite ordonarea obiectelor, care se află într-o relaţie logică. Segmentarea permite
utilizatorului să-şi organizeze programele şi datele sub forma unui ansamblu de segmente, fără să se preocupe de
implantarea lor fizică. De exemplu, fiecare procedură a unui program complex poate ocupa un segment distinct. În
calculatoarele cu adresare segmentată fiecare segment este reperat de un descriptor, numele acestor descriptori fiind
direct interpretate de procesor.
5.1.2.3. Contexte şi medii
Mulţimea obiectelor accesibile unui proces variază în timp. Iată câteva considerente:
1. Decompoziţia aplicaţiilor. Metodele de decompoziţie, utilizate pentru structurarea unei aplicaţii complexe,
definesc componentele (module, proceduri, etc.). Fiecărei componente i se asociază o mulţime distinctă de
obiecte accesibile.
2. Gestiunea dinamică. Mulţimea obiectelor accesibile unui proces îşi poate modifica compoziţia din
considerente, legate chiar de natura aplicaţiei: obiectele pot fi create sau distruse în timpul execuţiei.
3. Protecţia. O modalitate simplă de a împiedica un proces să aştepte un obiect, accesul la care îi este interzis,
este de a suprima toate căile de acces ale procesului spre acest obiect pentru durata interdicţiei. Vor fi
evitate în acest fel cheltuieli exagerate la execuţie.
4. Eficacitatea. Dacă un obiect este căutat într-o mulţime de alte obiecte, căutarea este cu atât mai eficace cu
cât mulţimea are mai puţine elemente.
Trebuie, deci, să luăm în consideraţie atât posibilitatea evoluţiei dinamice a mulţimii obiectelor, cât şi a căilor de
acces la aceste obiecte. Introducem pentru aceasta noţiunile care urmează.
Vom numi lexică o mulţime de identificatori. Mulţimea obiectelor, desemnate de identificatorii lexicii la un moment
de timp dat, se numeşte context asociat la această lexică (adică mulţimea obiectelor pentru care există o cale de acces
pornind de la unul dintre aceşti identificatori). Starea de execuţie a unui context este starea mulţimii obiectelor, care
constituie acest context.
Fiind dată doar lexica nu putem defini un context: mai trebuie să fie specificate regulile de interpretare, care vor fi
aplicate identificatorilor din cadrul lexicii. Vom numi mediu mulţimea formată dintr-o lexică şi informaţiile (programe,
date, reguli de interpretare) necesare la utilizarea acestei lexici. Aceste informaţii pot lua diferite forme în dependenţă
de limbajul utilizat (limbaj de comandă, limbaj de programare).
Vom numi accesibilitate a unui identificator într-un program regiunea programului în care acest identificator este
valid, adică poate fi utilizat ca origine a unei căi de acces. Altfel spus, un proces poate utiliza acest identificator pentru a
desemna un obiect atunci când el execută partea în cauză a programului.
Noţiunea de durată de existenţă sau de viaţă a unui obiect poate fi extinsă şi pentru căile de acces, înţelegând prin
aceasta perioada de timp în care acestea există (intervalul de timp care separă crearea de distrugere).
Atunci când un proces execută un program, mulţimea obiectelor la care procesul are acces este definită pentru orice
moment de timp, aplicând identificatorilor valizi în aceste momente de timp regulile de interpretare, specificate de
mediul curent: regăsim noţiunea de context pentru execuţia unui proces, introdusă în capitolul 3.
Exemplul 5.2. Fie procesul (presupus unic) asociat utilizatorului unui sistem interactiv. În mediul, definit de interpretorul limbajului de comandă,
lexica conţine numele fişierelor accesibile utilizatorului. Atunci când utilizatorul comandă execuţia unei proceduri, mediul se
modifică: lexica conţine identificatorii definiţi în interiorul procedurii de regulile de accesibilitate ale limbajului şi interpretaţi conform
regulilor proprii acestui limbaj.
ident.
context
reguli de
lexica interpretare obiect
cale de acces
mediul
Fig.5.3. Contextul de execuţie a unui proces
Starea de execuţie a unui proces (“valoarea” obiectelor contextului său) se poate modifica la execuţia fiecărei
instrucţiuni, însă conţinutul contextului său (identitatea obiectelor care-l formează), se schimbă cu o frecvenţă mai mică.
Iată evenimentele principale care pot modifica conţinutul contextului unui proces:
1) Schimbarea mediului, implicând o modificare a compoziţiei lexicii şi, eventual, aplicarea unor reguli de
interpretare noi: apel de procedură, intrarea într-un bloc nou (într-un limbaj cu structură de blocuri),
schimbarea catalogului curent (într-un limbaj de comandă).
2) Modificarea explicită a căii de acces, pornind de la un identificator al lexicii: asocierea unui fişier sau unui
periferic unui flux de intrare-ieşire.
3) Crearea sau distrugerea explicită a unui obiect desemnat de un identificator din lexică: crearea sau
distrugerea unui fişier, alocarea sau eliberarea unei variabile administrate dinamic.
Examinând aceste cazuri putem diferenţia durata de viaţă a unui obiect, a unui identificator, care desemnează acest
obiect şi cea a unei căi de acces, care conduce la obiectul în cauză. Sunt posibile diferite situaţii: un identificator poate fi
legat succesiv de diferite obiecte; reciproc, un obiect poate succesiv (sau simultan) să fie desemnat de mai mulţi
identificatori diferiţi; un obiect poate deveni inaccesibil (nici o cale de acces nu conduce la el). Existenţa obiectelor
inaccesibile pune problema recuperării spaţiului ocupat de acestea: tehnici speciale de “adunare a fărămiturilor”, permit
rezolvarea acestei probleme.
Exemplul 5.3. Cu titlu de exemplu vom indica diferite clase de obiecte, accesibile unui proces în cursul execuţiei unei proceduri, exprimată într-un
limbaj de programare de nivel înalt. Aceste clase diferă din punct de vedere a duratei de viaţă, duratei legăturii şi modului de partajare
a obiectelor.
1) Obiecte interne: acestea sunt instrucţiunile, care compun textul procedurii. Ele sunt desemnate de etichetele, utilizate pentru
instrucţiunile de ramificare. Durată lor de viaţă coincide cu durată de viaţă a procedurii.
2) Obiecte locale: acestea sunt variabilele, declarate în interiorul procedurii. Aceste obiecte sunt create la fiecare apel al procedurii
şi distruse la retur. În cazul unui apel recursiv, un exemplar nou al fiecărui obiect local este creat la fiecare apel şi identificatorul
său desemnează ultimul exemplar creat (celelalte rămânând inaccesibile până la returul la nivelul corespunzător).
3) Obiecte remanente şi obiecte globale: acestea sunt obiectele care existau deja la apelul procedurii şi care vor supravieţui la retur;
durata lor de viaţă este fie cea a procesului (obiecte remanente), fie cea a unei proceduri, care înglobează procedura dată (obiecte
globale).
4) Obiecte externe: sunt obiectele construite şi păstrate independent de procedura şi procesul considerat (alte proceduri, fişiere,
etc.). Durata lor de viaţă nu depinde de cea a procedurii sau a procesului; ele pot fi create sau distruse în mod dinamic în timpul
execuţiei procedurii.
5) Parametri: parametrii formali sunt identificatori, utilizaţi în interiorul procedurii şi care sunt legaţi doar în momentul apelării.
Obiectele legate de acestea sunt numite parametri efectivi sau activi; parametrii efectivi sunt furnizaţi de către procedura apelantă
sau sunt obiecte externe. Legătura dintre parametrii formali şi cei efectivi poate lua diferite forme în dependenţă de regulile
definite în limbajul de programare: apelare prin nume, prin valoare, prin referinţă. Aceste forme diferă prin momentul stabilirii şi
permanenţei legăturii. Legătura dispare la returul din procedură. ◄
În cazul în care mai multe procese partajează o procedură, fiecare proces posedă un set propriu de obiecte locale,
remanente, globale. Obiectele externe sunt în exemplar unic, ca şi textul (invariant) al procedurii.
5.1.3. Legarea
Numim legare procesul construirii unei căi de acces. Acest proces acoperă o varietate mare de situaţii, care vor fi
analizate din mai multe puncte de vedere: natura relaţiei de desemnare, momentul legării, permanenţa legăturii. Vom
prezenta mai jos şi tehnicile principale utilizate.
Legarea obiectelor unui program poate fi efectuată la diferite momente de viaţă a programului în sistem:
1) În momentul scrierii programului. Este cazul unui program scris direct în cod binar când fiecare obiect este
desemnat prin adresa absolută a amplasamentului, care-l conţine. Un atare program poate fi imediat executat, dar orice
modificare este dificilă şi conţine un risc ridicat de eroare. În practică, unicele obiecte legate la etapa scrierii
programului sunt notaţiile universale, care desemnează constantele.
2) La una din fazele de translatare (asamblare sau compilare). Legătura este definitivă şi identificatorii sunt
înlocuiţi prin adrese absolute. Dezavantajul este că programul nu poate fi deplasat în memorie fără a fi recompilat (dacă
nu există mecanisme de translatare a adreselor). De asemenea, legătura stabilită la translatare nu este decât parţială:
identificatorii nu sunt înlocuiţi de adrese absolute, ci relative începând cu originea programului (deplasare).
3) La o fază de încărcare şi editare a legăturilor. Faza încărcării are drept scop înlocuirea adreselor relative prin
adrese absolute, fixând originea programelor în memorie. Faza editării legăturilor are ca scop stabilirea legăturii
referinţelor externe (să ne amintim, că vorbim despre identificatorii, care desemnează obiecte construite sau păstrate
independent de programul în cauză). Încărcarea şi editarea legăturilor pot fi combinate într-o singură operaţie sau
realizate separat. Algoritmii utilizaţi sunt descrişi în 5.3.
O operaţie analogică editării legăturilor este cea a legării fluxurilor de intrare-ieşire cu fişierele sau perifericele. Ca
şi editarea legăturilor, această operaţie, descrisă în 5.2.3.2 poate fi realizată în prealabil sau în timpul execuţiei.
Cu excepţia sistemelor de înlănţuire a programelor, numite “compile and go” în care programele sunt traduse şi executate imediat; aceste sisteme
sunt prevăzute pentru programe scurte, destinate unei singure execuţii.
Vom găsi în 5.4.2 şi 5.4.3 o cercetare mai detaliată a mecanismelor de protecţie şi câteva exemple de utilizare a
acestora în sistemele de operare.
5.1.4.3. Problemele protecţiei
Prezentăm succint câteva probleme, legate de implementarea protecţiei în sistemele informatice.
1) Protecţie ierarhizată
catalogul
(a) (b) utilizatorilor
catalog
rădăcina
cataloagele
Corina ... Alex Victor ... Eugen ... utilizatorilor
catalog
doc test doc ... fiş_exe
demo
fişier
program
în Pascal
legătură
date calculatorul
program obiect în
adrese relative
Memoria fizică
s d
L
L a
Tabelul segmentelor
nume local
nume
global
punct de
intrare
proceduri proceduri
date date
registre segment de
Victor Beşliu de bază p.19
legătură din 20
modul apelant modul apelat
În programul unui modul M apelul procedurii cu numărul k a modulului, descris de amplasamentul cu numărul n al
segmentului de legătură este realizat cu ajutorul unei instrucţiuni call n, k.
1) Permite oare această schemă realizarea mai multor module care ar avea proceduri comune şi variabile globale
proprii? Care sunt avantajele unei atare posibilităţi?
2) Descrieţi detaliat secvenţa operaţiilor, care vor fi executate la apelul unei proceduri externe a unui modul şi la
returul din procedură.
call n, k
3) Permite oare această schemă editarea dinamică a legăturilor? Descrieţi structurile de date necesare şi principiul de
realizare.
Interpretarea Interpretarea
numelor locale numelor externe
Nume Realizarea
interne funcţiilor de acces
logic
Adrese
fizice Alocarea Realizarea
memoriei I-E
secundare fizice
Această schemă nu trebuie să fie considerată drept un cadru rigid, care ţine cont de toate modurile de organizare a
SGF, ci doar ca un ghid pentru stabilirea funcţiilor şi structurilor de date mai frecvente. Planul adoptat pentru restul
capitolului va urma, într-un mod descendent, ierarhia astfel stabilită.
Metodele de organizare logică a fişierelor (reprezentarea datelor, realizarea funcţiilor de acces) sunt aplicaţii directe
ale structurilor de date: tabele, fire de aşteptare, liste, etc., care sunt tratate în alte discipline. Ne vom opri la o succintă
descriere a organizării uzuale, făcând trimitere la literatura de specialitate pentru studii mai aprofundate. Interesul
principal al acestei descrieri este de a elucida restricţiile introduse de organizarea fizică a fişierelor.
6.2.2. Acces secvenţial
În cadrul unei organizări secvenţiale înregistrările sunt ordonate şi pot fi desemnate de valori întregi consecutive.
Totuşi, aceste numere de ordine nu pot fi folosite în cadrul funcţiilor de acces; este permisă doar utilizarea funcţiei
“succesor”. Accesul secvenţial este modul obişnuit de utilizare a unui fişier, implantat fizic pe un suport în care accesarea
amplasamentelor este ea însăşi secvenţială, cum ar fi banda magnetică.
Un fişier f poate fi deschis pentru citire sau scriere. Unele organizări autorizează scrierea începând de la o înregistrare
oarecare (v. exemplul din capitolul 9). Vom considera că scrierea se face la sfârşitul fişierului şi deschiderea pentru
scriere iniţializează fişierul în “vid”.
Deschiderea pentru scriere este realizată prin operaţia:
deschide(mod):
if mod=citire then
f.rest:=<şirul înregistărilor fişierului>
else
f:=<vid>
endif;
f.mod:=mod;
avansare
unde funcţia avansare este definită după cum urmează:
if f.rest=vid then
f.sfârşit:=true
else
articol 2 al2=f(cheie2)
f(cheie2)= f(cheie3)
cheie 1
cheie 2 funcţie de al1=f(cheie1)
f(cheie1) articol 1
dispersare
cheie 3
tratare
coliziuni
(coliziune între cheie1 şi cheie3)
articol 3 al 3
Cheie 1
Cheie 2 articol 1
Cheie 3
articol 3
tabelul indicilor
autorilor
tabelul indicilor
editorilor
tabelul indicilor
autorilor înregistrări
tabelul indicilor
editorilor
tabelul indicilor
anilor
Ultimul bloc, care poate fi utilizat parţial, trebuie să conţină indicaţii despre numărul de amplasamente ocupate. Deci,
este necesar un amplasament în fiecare bloc pentru această informaţie sau cel puţin un bit (indicator) pentru marcarea
ultimul bloc. Deoarece există un pointer la ultimul bloc este simplu să extindem un fişier, adăugând informaţii la sfârşit.
Acest mod de alocare este bine adaptat accesului secvenţial. Ca rezultat, putem accesa un bloc doar respectând
înlănţuirea; accesul direct este costisitor, deoarece fiecare citire a unui pointer necesită o accesare a discului. La fel şi
extinderea altfel, decât la sfârşit, este foarte dificilă: trebuie să permitem existenţa blocurilor parţial pline, să prevedem o
dublă înlănţuire, etc. Utilizarea alocării înlănţuite este limitată de cazul sistemelor mici, în special pentru organizarea
fişierelor pe dischete.
6.3.2.2. Tabele de implantare
În cazul accesului direct timpul de acces la un bloc trebuie să nu depindă de adresa sa, ceea ce poate fi obţinut punând
toţi pointerii într-un tabel unic de implantare. Descriem mai multe variante ale acestei metode, care diferă prin modul de
organizare a tabelului. Problema principală este garantarea uniformităţii timpilor de acces pentru tabelele de lungime
mare şi permiterea inserării şi distrugerii blocurilor în orice punct al fişierului.
1) Tabel unic
Figura 6.8 (a) descrie o organizare cu tabel unic. Lungimea fişierului este limitată de numărul blocurilor pe care
descriptorul le defineşte în tabel (el însuşi conţinându-se într-un număr întreg de blocuri).
2) Tabel înlănţuit
Conform organizării din fig.6.8 (b) tabela de implantare constă dintr-o suită de blocuri înlănţuite. Putem depăşi în
acest fel limitarea dimensiunii unui fişier, devine posibilă inserarea blocurilor în mijlocul fişierului, cu condiţia rezervării
unor amplasamente libere în tabel. Reorganizarea generată de inserare este legată de un bloc al tabelului, iar dimensiunea
tabelului de implantare este limitată de costul căutării în acest tabel. Pentru tabele mari organizarea descrisă este mai
eficace.
3) Tabele cu mai multe nivele
Figura 6.9 descrie o organizare în care tabelul de implantare a fişierului este organizat în mod arborescent, pe niveluri
(de obicei, două sau trei niveluri).
Din raţionamente de securitate (v. 6.5), starea liber sau ocupat a unui bloc este păstrată chiar în blocul propriu-zis.
HANDLE hToken;
if (pszDomainName == NULL)
{
BYTE bSid[8 + 4 * SID_MAX_SUB_AUTHORITIES];
ULONG cbSid = sizeof(bSid);
ULONG cchDomainName = countof(szDomainName);
SID_NAME_USE Use;
if (phToken == NULL)
_VERIFY(CloseHandle(hToken));
else
*phToken = hToken;
return TRUE;
}
Câteva comentarii sunt necesare. În primul rând, toate string-urile de intrare sunt copiate în masive speciale din stiva
funcţiei. Aceasta este necesar din cauza că toţi parametrii funcţiei sunt declaraţi constante string, iar LogonUser primeşte
indicatori la string-uri, care pot fi modificate. În unele condiţii LogonUser poate scrie în parametrii pe care îi primeşte
ceea ce poate conduce la prohibitarea protecţiei memoriei. Doi: conform celor menţionate mai sus, unele versiuni timpurii
ale sistemului de operare Windows NT nu permit valoarea NULL pentru numele domenului. Această situaţie va fi tratată
în mod individual şi numele corespunzător pentru domen este depistat cu ajutorul funcţiei LookupAccountName.
Observăm, că utilizarea funcţiei LogonUser nu este complicată, dar în Windows NT şi Windows 2000 are o restricţie
substanţială: utilizatorul, care apelează această funcţie trebuie să posede prioritatea SE_TCB_NAME. Este o prioritate
foarte înaltă, chiar nici administratorii nu o posedă, semnificând controlul total asupra sistemului. TCB - Trusted
Computing Base (Baza Calculelor Sigure, în care poţi avea încredere) este o componentă a sistemului de calcul, care
asigură îndeplinirea politicii securităţii. Este un cod, executat în regim de nucleu şi un cod de regim user, executat în
contextul informaţiilor de evidenţă, care are prioritatea TCB. Deşi nu este periculos să fie acordată această prioritate
înregistrării de evidenţă, destinate execuţiei unui serviciu de sistem, Microsoft nu recomandă acest lucru, ci recomandă să
fie executat un cod, care cere prezenţa priorităţii TCB în contextul înregistrării de evidenţă de sistem. Folosirea
înregistrării de evidenţă de sistem are un avantaj: aceasta nu posedă parolă, în rezultat ea nu poate fi furată sau calculată.
Dacă nu este respectată recomandarea Microsoft, securitatea sistemului este redusă la zero, controlul parolei devenind
inutil.
Necesitatea prezenţei priorităţii TCB restricţionează substanţial domeniul de utilizare a metodei date. În Windows XP
LogonUser nu mai cere prezenţa priorităţii TCB la apelant, dar numărul de copii Windows NT şi Windows 2000 este
încă foarte mare.
ULONG lRes;
CSspiClient Client;
CSspiServer Server;
Client.FreeBuffer(pRequest);
pRequest = NULL;
Server.FreeBuffer(pResponse);
pResponse = NULL;
}
if (pRequest != NULL)
Client.FreeBuffer(pRequest);
if (pResponse != NULL)
Server.FreeBuffer(pResponse);
if (lRes != ERROR_SUCCESS)
return SetLastError(lRes), FALSE;
return TRUE;
}
În codul iniţial al funcţiei CheckPassword_SSPI nu există apelări directe a funcţiei SSPI – toate apelurile sunt incluse
în superclasele СSspiClient şi CsspiServer. Aceasta permite pe de o parte evidenţierea schimbului de mesaje între
client şi server, iar pe de altă parte – folosirea acestor clase în calitate de bază, dacă se doreşte realizarea autentificării de
reţea în aplicaţie.
Lucrul începe cu crearea şi iniţializarea obiectelor clientului şi ale serverului, în procesul de iniţializare obiectului
clientului fiindu-i transmise informaţii despre utilizator. Apoi este apelată metoda CSspiClient::Start, pentru a genera
cererea iniţială de autentificare şi are loc trecerea în ciclul de mesaje. Aici funcţia apelează metoda
CSspiServer::Continue şi CSspiClient::Continue. Aceste metode primesc la intrare mesajul celeilalte părţi şi
returnează mesajul de răspuns. Ciclul de mesaje durează până în momentul în care serverul stabileşte, că autentificarea s-a
petrecut cu succes sau invers. Pentru autentificarea NTLM în Windows NT 4.0 şi Windows 2000 este caracteristic
următorul moment: dacă un client încearcă să intre în sistem cu un nume necunoscut nici pentru sistemul local, nici
pentru domene, şi în sistemul local nu este blocată înregistrarea de evidenţă a oaspeţilor, atunci autentificarea se termină
cu succes, iar clientul intră în sistem sub numele înregistrării locale de evidenţă a oaspeţilor. Aceasta s-a realizat din
dorinţa compatibilităţii cu produsul mai vechi al firmei Microsoft NT Lan Manager (de unde şi vine numirea NTLM).
De aceea, în caz de succes, este apelată metoda CSspiServer::CheckGuest, care controlează, dacă nu cumva succesul
autentificării se datorează acestui moment. În sfârşit, dacă este necesar token-ul utilizatorului, funcţia apelează metoda
CSspiServer::GetToken, responsabilă de obţinerea token-ului. Cercetarea claselor CSspiClient şi CsspiServer, care
necesită o studierea mai amănunţită a interfeţei SSPI, este lăsată ca exerciţiu.
6.5.4.3. Funcţia NetUserChangePassword
Utilizarea acestei funcţii pentru autentificare are loc conform codului care urmează:
BOOL CheckPassword_ChangePwd(
IN PCTSTR pszDomainName,
IN PCTSTR pszUserName,
IN PCTSTR pszPassword,
USES_CONVERSION;
if (lRes == ERROR_INVALID_PASSWORD ||
lRes == NERR_UserNotFound)
return SetLastError(ERROR_LOGON_FAILURE), FALSE;
return TRUE;
}
Există mai multe considerente, care nu recomand utilizarea acestei funcţii pentru autentificare. Principalul considerent
este faptul, că funcţia NetUserChangePassword nu este destinată autentificării utilizatorilor.
catalog
fişier obişnuit
fişier special
SGF la distanţă
cale
TDA
nume local
0
TFD
nmax
exec ptr2
utilizatorul 2
[în memorie]
[pe disc]
descriptor
zona descriptorilor
blocuri
Fig.6.12. Descriptorii fişierelor în Unix
Citirea şi scrierea are loc pornind de la o poziţie curentă, definită de un pointer. Aceste operaţii incrementează în mod
automat pointerul cu numărul de caractere citite sau scrise. Primitiva lseek permite deplasarea explicită a pointerului.
Denumirea operaţiei Efectul Rezultatul
open(nume fişier, mod de acces) deschide fişierul cu modul de acces indicat nume local alocat (-1 dacă eşec)
close(nbloc) abrogă asocierea între numele local nbloc şi succes → 0, eroare → -1
fişierul (sau tub) asociat
dup(nbloc) dacă nbloc este numele local al unui fişier succes → nbloc1, eroare → -1
deschis, alocă un alt nume local nbloc1
sinonimul lui nbloc (desemnând acelaşi
fişier)
read(nbloc,tampon,ncar) citeşte ncar caractere din fişierul (sau tub) numărul de caractere citite efectiv
cu numele local nbloc în zona tampon (mai mic decât ncar, dacă s-a
ajuns la sfârşitul fişierului)
write(nbloc,tampon,ncar) scrie ncar caractere din zona tampon în numărul de caractere efectiv scrise
fişierul (sau tubul) cu numele local nbloc
lseek(nbloc,depl,orig) deplasează pointerul de citire-scriere depl poziţia curentă nouă, (-1 în caz de
caractere, pornind de la poziţia definită de eroare)
orig: 0 – începutul fişierului,
1 – poziţia curentă a pointerului
2 – sfârşitul fişierului
Notăm, că este posibil să deplasăm pointerul după sfârşitul fişierului. Efectul este sporirea lungimii fişierului, poziţiile
intermediare rămânând goale; aceste “găuri” nu ocupă loc în memorie.
6.6.3.3. Protecţia fişierelor în UNIX
Protecţia este asigurată cu ajutorul listelor de acces conform principiului din 6.5.3. Există trei moduri de acces
elementar: citire, execuţie, scriere pentru un fişier; consultare, acces, modificare pentru un catalog.
Pentru controlul drepturilor, utilizatorii nu sunt individualizaţi, ci partajaţi în trei clase: proprietarul fişierului, membrii
unui grup de utilizatori, restul utilizatorilor. Lista de acces la un fişier este, deci, de lungime fixă; ea enumără drepturile
de acces ataşate fiecărei grupe; ea poate fi modificată doar de proprietarul fişierului sau de administratorul sistemului. O
caracteristică originală a sistemului de protecţie este că proprietarul unui fişier poate fi schimbat.
De la începuturi UNIX a fost gândit ca un sistem de operare interactiv. Pentru a începe lucrul un utilizator trebuie „să
intre” în sistem, introducând de la terminal numele propriu de evidenţă (contul, account name) şi, poate, parola
(password), devenind astfel utilizator înregistrat al sistemului. Noii utilizatori sunt introduşi (înregistraţi) de către
administrator. Utilizatorul nu-şi poate modifica contul propriu, în schimb parola este la discreţia lui. Parolele sunt
codificate şi păstrate într-un fişier separat. Nici administratorul nu poate restabili o parolă uitată. Fiecărui utilizator
înregistrat îi corespunde un catalog propriu al SGF, numit home. La intrare utilizatorului i se conferă acces total la acest
catalog, inclusiv şi la toate cataloagele şi fişierele, care se conţin aici. Accesul la alte cataloage şi fişiere poate fi
restricţionat.
Deoarece UNIX este un sistem de operare multiuser, o problemă foarte actuală este problema autorizării accesului
utilizatorilor la fişierele SGF. Prin „autorizarea accesului” sunt considerate acţiunile sistemului, care conduc la permiterea
sau interzicerea accesului unui utilizator concret la un fişier dat în dependenţă de drepturile de acces ale utilizatorului şi
tm
Var(ts)
1 ρ=λts
Fig.7.2. Timpul mediu de răspuns pentru disciplina FIFO
t m (1 C t )
2 2 ts
tm(ts) = s s
cu (t s ) tdB(t ) (7.2)
2[1 (t s )] 2 0
t m (1 C t )
2 2
tm(ts) ≈ s s
(7.3)
2
pentru valori mari ale ts, unde ρ(ts) este aproape de λtms, fie ρ:
tm(ts) ≈ s s
(7.4)
2(1 ) 2
Figura 7.3 prezintă dependenţa timpului mediu de răspuns de timpul de servire cerut pentru cazurile FIFO şi Cererea
cea mai Scurtă Servită Prima (CSSP). Pentru disciplina de servire FIFO acest timp depinde doar de gradul încărcării
sistemului ρ, considerat de noi constant. Figura pune în evidenţă tratarea privilegiată a lucrărilor scurte.
tm
CSSP
FIFO
ts
Fig.7.3. Dependenţa timpului mediu de răspuns de timpul de servire
în cazul disciplinelor FIFO şi CSSP
În plan practic disciplina CSSP are două dezavantaje: ea prezintă un risc de privaţiune pentru cererile lungi, dacă
rata de sosire a cererilor scurte este ridicată şi necesită cunoaşterea apriori exactă a timpului de servire.
O modalitate de evitare a riscului de privaţiune este de a acorda cererilor priorităţi care vor creşte odată cu creşterea
timpului lor de aflare în firul de aşteptare, prioritatea iniţială fiind determinată de timpul de servire estimat. De exemplu,
în cadrul disciplinei HRN (Highest Response Ratio Next) prioritatea unei cereri la un moment de timp τ este dată de
relaţia
p(t) = [t(τ)+ts)]/ts (7.5)
unde t(τ) este timpul de aflare a unei cereri în firul de aşteptare (fie t(τ)= τ – τs, aici τs fiind momentul sosirii cererii), iar
ts timpul de servire estimat. Pentru două cereri cu acelaşi timp de aşteptare, prioritate are cererea mai scurtă. În practică,
priorităţile sunt recalculate în momente discrete de timp şi firul de aşteptare este reordonat la necesitate.
Ideea directoare a acestui algoritm este de a partaja echitabil procesorul, încercând să se menţină o valoare constantă
a raportului k = t/ts, unde t este timpul total de aflare a unei cereri în sistem. Dacă aceasta se respectă, totul se va petrece
pentru fiecare lucrare ca şi cum ea ar dispune de un procesor de k ori mai slab (mai puţin rapid) decât procesorul real.
Disciplina HRN privilegiază lucrările scurte, însă penalizarea lucrărilor de lungă durată este redusă de efectul priorităţii
variabile.
Algoritmii descrişi mai jos vizează la fel partajarea echitabilă a procesorului, dar nu necesită cunoaşterea apriori a
timpului de servire.
7.2.1.4. Caruselul şi modele derivate
În modelul caruselului (“round robin”) procesorul este alocat succesiv proceselor eligibile pentru o perioadă
constantă de timp τ, numită cuantă. Dacă un proces se termină sau se blochează înainte de sfârşitul cuantei, procesorul
este imediat alocat procesului următor. Această disciplină de servire este implementată ordonând procesele într-un fir de
aşteptare circular; un pointer de activare, care avansează cu o poziţie la fiecare realocare a procesorului, desemnează
procesul ales (fig.7.4).
ieşire
intrare
f_eligibil proc_ales
t(ts) t(ts)
CM PP CM
PP
CSSP
CSSP
ts ts
FIFO – prim sosit prim servit PP – procesor partajat
CSSP – cerere scurtă servită prima CM – carusel multinivel
Fig. 7.6. Compararea disciplinelor de alocare a procesorului
Putem aprecia, în conformitate cu gradul de încărcare a procesorului, avantajele acordate de diferite discipline de
servire lucrărilor de scurtă durată.
7.2.2. Disc de paginare
Vom cerceta acum metodele de gestiune a schimburilor între memoria principală şi un disc cu dispozitive de citire-
scriere (DCS, capuri) fixe. Astfel de discuri sunt organizate pe piste şi sectoare şi are câte un DCS per pistă.
Schimburile sunt comandate de un server care primeşte cererile de transfer; fiecare cerere presupune transferul unui
sector cu indicaţia direcţiei de transfer, o adresă în memorie şi una pe disc (pista şi sectorul) [17].
Vom cerceta două discipline de tratare a cererilor:
Cereri
(toate sectoarele)
Cerere a
sectorului i
Lungimea medie a unui fir de aşteptare, fiind inclusă şi cererea în curs de servire, este obţinută din formula
Pollaczeck-Khinchine:
t (1 Ct2s )
nm = λtms 1 ms (7.8)
2(1 t ms )
şi timpul mediu de servire este:
n R( N 1) (2 N 1)R
tm = m = 1 (7.9)
2 N 3[2 N R( N 1)]
2) Disc de paginare. Fiecare fir poate fi tratat independent, utilizând modelul lui Skinner (server cu restabilire), cu
λi = λ/N ts = R/N, tr = (N-1)R/N,
T=R S = t s + tr = R
Pentru un fir de aşteptare vid, ca şi pentru începerea tratării următoarei cereri, este necesar să se aştepte o rotaţie
completă. Lungimea medie a unui fir de sector este:
2 R 2 / N 2 R 1 1
nmi = (7.10)
2(1 R / N ) N N 2
şi timpul mediu de servire:
n R 2 / N N 2
tm = mi = R . (7.11)
i 2(1 R / N ) 2N
2N/R(N+1) N/R λ
Fig. 7.8. Compararea modelelor de administrare a discului
Compararea pragurilor de saturare pentru cele două discipline permite calcularea câştigului obţinut pentru discul de
paginare. Pragul de saturare este definit prin ρ = 1. Vom obţine în acest caz: pentru discul cu fir unic: λR(N+1)/2N = 1,
iar pentru discul de paginare: λR/N = 1.
Raportul pragurilor critice pentru λ este, deci, (N+1)/2; acest raport este o măsură a câştigului obţinut prin
organizarea firelor pentru sectoare.
Notăm prin A[i,*] vectorul format din linia i a matricei A. Dacă U şi V sunt doi vectori de aceeaşi lungime k, vom
conveni să scriem:
UV dacă şi numai dacă U[i] V[i] pentru i=0, 1,..., k-1
U<V dacă şi numai dacă U V şi UV.
Specificaţiile sistemului impun următoarele restricţii:
0 Aloc[i,*] Anunt[i,*] Res, pentru i=0,...,n-1
Aloc[i,*] Res
Disp 0 vectorul nul.
Aceste relaţii exprimă, pentru fiecare clasă de resurse, că anunţul nu poate depăşi numărul resurselor disponibile, că
cantitatea resurselor alocate unui proces nu poate depăşi anunţul său şi, în sfârşit, că sistemul nu poate aloca mai multe
resurse decât există în total. O stare a sistemului se numeşte realizabilă, dacă este conformă acestor specificaţii.
Fie E0 o stare realizabilă a sistemului. Încercăm să găsim un proces pi, care, dacă el era executat singur pornind de la
starea E0, utilizând totalitatea resurselor specificate de anunţul său, procesul ar putea ajunge până la sfârşit. Un
asemenea proces trebuie să verifice , în starea E0:
Anunt[i, *]-Aloc[i, *] Disp.
Presupunem că a fost găsit un astfel de proces, fie pi0, şi că el este executat până la sfârşit. El eliberează atunci toate
resursele sale şi sistemul trece într-o stare realizabilă E1, definită prin
DispE1=DispE0+Aloc[i0,*].
Operaţia poate fi repetată, căutând un proces nou pi1 şi tot aşa cât este posibil. Suita de procese, obţinută în acest
mod se numeşte fiabilă. O stare a sistemului se numeşte fiabilă, dacă, pornind din această stare, putem construi o suită
fiabilă completă (adică, care conţine toate procesele sistemului).
Urmând această definiţie, un sistem într-o stare fiabilă nu este în blocare, deoarece poate fi definită o ordonare a
proceselor, care permite execuţia tuturor proceselor. Putem demonstra afirmaţia reciprocă (exerciţiu): dacă un proces nu
este în blocare, el se află într-o stare fiabilă. Algoritmul bancherului se bazează pe această proprietate; el este executat la
fiecare cerere de resursă de un proces. Fie Cerere[i, j] numărul de resurse cerute din clasa j în starea curentă a
sistemului, de către procesul i.
if Aloc[i,j]+Cerere[i,j]>Anunt[i,j] then
<eroare> -- cererea totală > anunţul
else
if Cerere[i,j]>Disp[j] then