Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
- 1 -<br />
<strong>CAPITOLUL</strong> I<br />
DESCRIEREA SISTEMELOR DE OPERARE<br />
1.1. Sisteme de calcul( SC) şi sisteme de operare( SO)<br />
1.1.1. Introducere în SO; familii de SC<br />
Ce este un SO? SO este un sistem de programe care acţionează ca o interfaţă<br />
între utilizator şi echipamentul hard. Asigură accesul convenabil al utilizatorului la SC şi<br />
utilizarea eficientă a sa.<br />
Deoarece SO apare ca o interfaţă, SO are două roluri esenţiale:<br />
a) SO extinde arhitectura hard a SC;<br />
b) SO gestionează resursele solicitate de programele utilizator<br />
Exemplu. a) SC este compus din procesoare, memorie internă, dispozitive de<br />
intrare/ieşire( I/O), orologii, terminale, interfaţă de reţea etc. Arhitectura hard oferă<br />
elemente cu care se poate acţiona asupra acestor componente: instrucţiuni maşină,<br />
organizarea memoriei, sistemul I/O etc. Pentru programator e greu să ţină seama de<br />
convenţiile impuse de acestea. Programatorul scrie READ (f,t). Dacă ar fi să ţină seama<br />
de toate detaliile arhitecturale ar trebui să precizeze de pe ce fel de disc se citeşte (de<br />
masă, dischetă, hard), să comande poziţionarea capului de citire, să-l activeze. Există însă<br />
o rutină a SO care preia argumentele din READ şi rezolvă toate detaliile.<br />
b) Pe acelaşi SC şi în acelaşi timp lucrează trei programe distincte<br />
care solicită o aceeaşi imprimantă. SO gestionează utilizatorii şi le distribuie resursa<br />
imprimantă într-un mod raţional: memorează în trei fişiere pe disc liniile generate la<br />
ieşire de către fiecare program. Dacă un program s-a încheiat se listează fişierul<br />
corespunzător la imprimantă fără a fi întrerupt. După terminarea unei listări imprimanta<br />
va fi ocupată pentru listarea următoare.<br />
Generaţii, clase şi familii de calculatoare<br />
Specialiştii în calculatoare le-au împărţit în mai multe generaţii. Criteriile<br />
(temporale, tehnologice, de dezvoltare soft) sunt relative. Se va prezenta clasificarea dată<br />
de profesorul M.Drăgănescu în vol. "Calculatoarele electronice din generaţia a cincea",<br />
Editura Academiei, Bucureşti 1985.<br />
Gen Perioada Tehnologie<br />
CPU<br />
Tehnologie<br />
memorie<br />
Limbaje<br />
utilizate<br />
Performanţe de<br />
memorie şi CPU<br />
I 1946-<br />
1956<br />
Tuburi<br />
electronice<br />
Tambur<br />
magnetic<br />
Limbaj de<br />
asamblare<br />
mem: 2KO<br />
viteza: 10 4 I/S
- 2 -<br />
II 1957-<br />
1963<br />
Tranzistori Inele de ferită Limbaje de<br />
nivel înalt<br />
FORTRAN,<br />
COBOL<br />
mem: 32 KO<br />
viteza: 2·10 5 I/S<br />
III<br />
1964-<br />
1981<br />
Circuite<br />
integrate<br />
Mem.-<br />
semiconducto<br />
ri, discuri<br />
magnetice<br />
Limbaje de<br />
nivel foarte înalt<br />
Pascal, LISP<br />
mem: 2MO<br />
viteza: 5·10 6 I/S<br />
IV 1982-<br />
1989<br />
Circuite<br />
integrate pe<br />
scară largă şi<br />
foarte largă<br />
Mem.cu bule,<br />
discuri optice<br />
Limbaje<br />
orientate<br />
obiect<br />
mem: 8MO<br />
viteza: 3·10 7 I/S<br />
supercalculatoare<br />
V<br />
după<br />
1990<br />
Circuite<br />
integrate pe<br />
scară extrem<br />
de largă;<br />
maşini LISP şi<br />
PROLOG<br />
Arhitecturi<br />
paralele<br />
Limbaje<br />
concurente<br />
Limbajul<br />
NATURAL<br />
Limbaje<br />
funcţionale<br />
(LISP)<br />
limbaje logice<br />
(PROLOG)<br />
viteza: 10 9 -<br />
10 12 I/S<br />
memorare şi<br />
prelucrare<br />
cunoştinţe<br />
(inteligenţa<br />
artificială)<br />
vedere artificială<br />
tehnica vorbirii<br />
Familiile de calculatoare existente azi în lume se pot împărţi în clase:<br />
1) Microcalculatoare<br />
Folosesc ca CPU( unitate centrală de prelucrare) un microprocesor; operaţiile se<br />
fac asupra datelor reprezentate pe 8, 16, 32 şi 64 biţi; sunt sisteme interactive,<br />
monoutilizator<br />
a) Calculatoare personale familiale: la acestea ieşirea se face pe monitor<br />
TV, iar ca unitate de memorie externă se foloseşte caseta audio. Exemple: aMIC, PRAE,<br />
MC-85, TIM-S; SINCLAIR SPECTRUM (Anglia),C OMMODORE-64 (SUA)<br />
b) Microcalculatoare profesionale: dispun de configuraţie proprie:<br />
tastatură, monitor, suport magnetic. Exemple: M18, TPD, CUBZ, TDF, JUNIOR, ML16,<br />
FELIX-PC, APPLE, IBM-PC<br />
2) Minicalculatoare<br />
Minicalculatoarele apar după 1970; drept CPU folosesc o UC( unitate centrală)<br />
clasică pe 16 biţi (nu microprocesor); sunt sisteme interactive multiutilizator; sistemul<br />
I/O e orientat spre o magistrală unică (se impune legarea în paralel a perifericelor la<br />
magistrală). Exemple: fam. PDP11 (DEC-SUA), superminicalculator VAX-8600 (1985),<br />
VAX-8650 (1986) în prezent pe 32 biţi, CORAL, INDEPENDENT( producţie<br />
românească).<br />
3) Calculatoare medii-mari (main-frame)<br />
Apar după 1950; operează pe cuvinte de 32 biţi, au memorie mare, sunt sisteme<br />
seriale şi sunt foarte scumpe. Exemple: fam. IBM-360, FELIX C-256, C-512, C-1024, C-<br />
5000
- 3 -<br />
4) Supercalculatoare<br />
Au memorie internă de mare capacitate, eventual mecanisme de memorie virtuală,<br />
operanzi pe cuvinte de 32-64 biţi şi sunt sisteme multiprocesor. Exemple: fam. IBM-370<br />
cu seriile 145, 158, 168, CDC 6600, CDC CIBER, CRAY →CRAY II<br />
Cel mai reprezentativ este SC IBM AS/400 (are posibilităţi de configurare foarte<br />
variate) care se foloseşte pentru gestiunea activităţilor unei intreprinderi mari şi foarte<br />
mari, supravegherea activităţii unor trusturi de importanţă internaţională (societăţi de căi<br />
ferate, companii aeriene).<br />
Evoluţia SO<br />
Teoria SO s-a dezvoltat iniţial pentru sisteme mari. Mini şi microcalculatoarele au<br />
preluat părţi din această teorie. La interval de 8-10 ani conceptele de SO sunt preluate de<br />
către noile familii de calculatoare( de exemplu prelucrarea conceptelor SO MULTICS de<br />
către UNIX pentru minicalculatoare şi migrarea către microcalculatoare).<br />
De asemenea, procedeele de parametrizare şi configurare ale SO în momentul<br />
lansării în execuţie au apărut încă de la sistemele seriale. Metoda a fost preluată şi<br />
folosită la toate tipurile de calculatoare. Acestea au extins procedeul la produsele<br />
program şi la mediile de programare de largă utilitate publică. Prin tehnica configurării<br />
utilizatorul este liber să-şi ajusteze SO astfel încât acesta să fie folosit optim la<br />
configuraţia hard şi soft existentă.<br />
Au început să fie proiectate SO sub forma unor obiecte abstracte care colaborează<br />
între ele după reguli foarte simple şi precise.<br />
La prima Conferinţă ACM Symposium on Operating Systems, 1967 E.W.Dijkstra<br />
a prezentat un raport privind organizarea soft a proiectului de SO THE (Technische<br />
Hogeschool Eindhoven). Sistemul THE este împărţit în 7 nivele, fiecare nivel este<br />
compus dintr-o colecţie de obiecte abstracte şi reguli care le guvernează (materializate<br />
prin primitive). Structura internă a unui obiect la un nivel este invizibil la alt nivel, dar<br />
poate fi exprimată în termenii obiectelor şi operaţiilor de la nivelele inferioare.<br />
Această utilizare a obiectelor abstracte este folosită pe scară din ce în ce mai largă<br />
şi azi. Semnificativă este utilizarea programării orientate obiect la descrierea elementelor<br />
grafice de interfaţă om-calculator. În acest fel se "umanizează" interfaţa cu SO, aceasta<br />
devenind relativ independent de SO( ex. suprafaţa de operare X Windows sub UNIX).<br />
1.1.1. Evoluţia SC şi a principalelor tehnici din SO<br />
a) Generaţia I<br />
Primele calculatoare (1945-1955) dispun numai de echipament hard şi au la baza<br />
construcţiei lor tuburi electronice. La acest SC utilizatorul introduce programul (codificat<br />
binar sau hexa) în memorie de la o consolă sau panou. Apoi îl lansează în execuţie, îi<br />
vizualizează rezultatele şi eventual îl depanează.<br />
b) Generaţia II<br />
Apare odată cu apariţia tranzistorului. În acelaşi timp apar cititorul de cartele,<br />
banda magnetică, imprimanta. Pentru utilizarea noilor elemente de I/O apar primele<br />
rutine de interfaţă (drivere) care asigură legătura dintre dispozitivul I/O, memorie şi CPU.<br />
Aceste rutine sunt considerate istoric primele programe care participă la un SO.
- 4 -<br />
Apar primele produse soft prin care se revoluţionează programarea: asambloare,<br />
linkeditoare, compilatoare etc. Cum sunt manipulate aceste produse necesare execuţiei<br />
unui program? Ele sunt depozitate pe cartele perforate sau pe benzi magnetice.<br />
Operatorul lansează în execuţie citirea cartelelor, încarcă de pe bandă compilatorul, îl<br />
lansează în execuţie. Deci caracteristic acestor sisteme este faptul că fiecare fază a unei<br />
lucrări presupune intervenţia umană.<br />
Sisteme seriale cu monoprogramare<br />
Se numeşte fază de elaborare a unui program una din următoarele activităţi:<br />
- editarea textului sursă cu calculatorul;<br />
- compilarea unui program;<br />
- editarea legăturilor programului;<br />
- lansarea în execuţie a programului<br />
- depanarea.<br />
Se numeşte job o succesiune de faze relativ la un program.<br />
Intervenţia umană între faze presupune o utilizare ineficientă a SC. Pentru<br />
evitarea acestui lucru apare conceptul de încărcare automată a joburilor şi fazelor. Se<br />
creează în acest scop un mic program numit monitor rezident care are ca sarcină<br />
principală asigurarea înlănţuirii joburilor şi fazelor.<br />
a) Programatorul inserează printre cartelele programului nişte cartele speciale<br />
numite cartele de comandă (au în prima coloană simboluri speciale). Se defineşte astfel<br />
un limbaj de control al joburilor.<br />
b) Monitorul rezident este un program permanent activ, operaţiile de I/O se fac de<br />
către monitor; zona de memorie a monitorului nu poate fi modificată de către utilizator,<br />
iar acesta nu poate comanda oprirea sistemului. Toate cererile de I/O ale utilizatorului<br />
sunt solicitate de către acesta monitorului prin apeluri sistem ( de exemplu o instrucţiune<br />
read generează un apel sistem). Apar deci modurile de lucru<br />
- monitor (master, privilegiat, supervizor)<br />
- utilizator (slave, neprivilegiat)<br />
c) O alt sarcină a monitorului este controlul depăşirii timpului de folosire a CPU.<br />
Utilizatorului i se acordă un timp maxim de folosire, după trecerea căruia se întrerupe<br />
automat execuţia programului sau se solicită acordul operatorului uman pentru<br />
continuarea lui.<br />
Deci, principalele sarcini ale monitorului sunt:<br />
a) înlănţuirea fazelor şi a joburilor pe baza instrucţiunilor date de către utilizator<br />
prin intermediul limbajului de control;<br />
b) coordonarea alternării între modurile de lucru supervizor şi utilizator;<br />
c) evitarea ciclurilor infinite prin limitarea timpului de folosire a CPU.<br />
Tipul de SO descris se numeşte serial, joburile executându-se unul după celălalt.<br />
Se mai folosete şi termenul de prelucrare pe loturi (batch processing) sugerând că se<br />
prezintă spre execuţie mai multe joburi, unul după celălalt. CPU nu se ocupă de alt job<br />
până nu îl termină pe cel curent, deci se lucrează în regim de monoprogramare.
- 5 -<br />
Sisteme seriale cu multiprogramare<br />
În sistemele seriale simple CPU aşteaptă mult din cauza diferenţelor mari de<br />
viteză dintre echipamentele electronice ale CPU şi echipamentele mecanice ale<br />
dispozitivului I/O ( de exemplu un cititor rapid de cartele citeşte 300 cart/min, iar un<br />
compilator traduce un program de 300 instrucţiuni în 60 sec.).<br />
Dezvoltarea arhitecturii a dus la apariţia canalului de intrare-ieşire. Acesta este<br />
un procesor specializat pe operaţii de I/O care poate funcţiona în paralel cu CPU. Pentru a<br />
fi lansat acesta primeşte de la CPU o comandă de efectuare a unei operaţii I/O, iar după<br />
lansare cele două procesoare îşi continuă activitatea în paralel. La sfârşitul operaţiei de<br />
I/O canalul anunţă CPU prin intermediul unei întreruperi.<br />
Fiecare periferic conţine o zonă tampon proprie capabilă să păstreze o<br />
înregistrare. CPU pune la scriere informaţia din memorie în zona tampon. Perifericul ia la<br />
scriere informaţia din zona tampon şi o pune pe suport, iar la citire acţionează invers.<br />
Viteza de lucru a CPU este mult mai mare decât a perifericului.<br />
Între CPU şi periferic există 3 moduri fundamentale de interacţiune:<br />
a) aşteptare reciprocă: în fiecare moment acţionează doar un procesor sau CPU<br />
sau canalul I/O;<br />
b) polling efectuat de către CPU: CPU foloseşte o instrucţiune maşină test pe<br />
care o execută periodic asupra perifericului. Dacă perifericul este liber, CPU lansează o<br />
operaţie I/O şi apoi cele două procesoare lucrează în paralel. Tehnica sondării<br />
perifericului se numeşte polling; o caracteristică importantă este frecvenţa cu care se face<br />
testarea. Tehnica polling se foloseşte pentru SC interactive multiutilizator pentru legarea<br />
cu terminale de teletransmisie.<br />
c) întrerupere lansată de către periferic. O întrerupere este un semnal hard care<br />
perturbă execuţia firească a instrucţiunilor dintr-un program în curs. La apariţia unei<br />
întreruperi se suspendă temporar programul în curs şi se lansează în execuţie o rutină<br />
aflată la o adresă fixă în memorie. Pentru fiecare tip de semnal de întrerupere se asociază<br />
o adresă fixă în memorie, în această locaţie se află adresa rutinei de întrerupere (rutină<br />
numit handler). Pe timpul tratării unei întreruperi în memorie se află atât programul<br />
suspendat cât şi rutina de întrerupere. Acţiunile desfăşurate la apariţia unei întreruperi<br />
sunt:<br />
- se reţine adresa instrucţiunii ce urmează a se executa în program;<br />
- se execută instrucţiunile rutinei de întrerupere;<br />
- se reia activitatea programului suspendat la adresa reţinută.<br />
Tehnica întreruperilor este utilizată la sistemele actuale. In acest mod se realizează<br />
comunicarea între SC şi periferice.<br />
În prezent SC folosesc 2 tipuri de canale:<br />
- selector: pentru schimburi dintre memorie şi periferic rapide;<br />
- multiplicator: lucrează simultan cu mai multe periferice (ex. USM - la SC<br />
FELIX, 470 KO/sec).<br />
Apariţia canalelor I/O a permis abordarea unor tehnici de exploatare eficientă a<br />
CPU.<br />
a) Utilizarea zonelor tampon multiple<br />
Se presupune că un program are de efectuat citiri, iar rezultatul fiecărei citiri este<br />
folosit în calcule. După ce s-a făcut o citire într-o zonă tampon, CPU cere imediat<br />
canalului să efectueze în avans încă o citire. În momentul în care canalul I/O a încheiat a
- 6 -<br />
doua citire, iar CPU solicită noi date, acestea sunt deja disponibile în a doua zonă<br />
tampon. Se lansează apoi în avans o nouă citire ş.a.m.d. Extinderea procedeului la mai<br />
multe zone tampon este imediată. Această tehnică funcţionează în ipoteza că dacă pentru<br />
schimbul cu un periferic a fost ocupată o anumită zonă de memorie, atunci ea este<br />
afectată exclusiv perifericului, pe toată durata schimbului. În prezent rutinele de I/O din<br />
SO moderne au facilităţi de lucru cu zonele tampon.<br />
b) Conceptul de multiprogramare: exprimă modul de exploatare a unui SC cu<br />
un singur procesor central care presupune existenţa simultan în memoria internă a mai<br />
multor programe care se execută concomitent. Primele SC ce lucrează în regim de<br />
multiprogramare apar înainte de 1965, odată cu apariţia plăcilor cu circuite integrate. Se<br />
poate vorbi deja de GENERAŢIA a III-a de calculatoare.<br />
Lucrul în multiprogramare se desfăşoară astfel: în fiecare moment CPU execută o<br />
instrucţiune a unui program - acest program este în starea RUN; alte programe aşteaptă<br />
apariţia unui eveniment extern (terminare I/O, scurgerea unui interval de timp) şi sunt în<br />
starea WAIT sau sunt pregătite de execuţie, adică în starea READY. Trecerea din starea<br />
RUN în starea WAIT este comandată de programul însuşi, trecerea din starea RUN în<br />
starea READY şi invers este comandată de SO pe baza unui algoritm de planificare.<br />
Pentru a lucra în multiprogramare este necesar ca:<br />
- SC să dispună de sistem de întreruperi pentru semnalarea evenimentelor externe;<br />
- SO să gestioneze, aloce şi protejeze resursele între utilizatori (memorie,<br />
periferice, fişiere, timp fizic).<br />
c) Conversii off-line: sisteme SPOOLING:<br />
Tehnica constă în: conţinutul cartelelor ce vor fi prelucrate este copiat într-un<br />
fişier pe bandă sau disc magnetic; suportul magnetic este transmis SC ca intrare standard.<br />
Analog rezultatele, sub forma unor linii pe imprimantă, sunt depuse întâi într-un fişier pe<br />
bandă sau disc, iar la terminarea lucrului conţinutul fişierului este listat la imprimantă.<br />
Tehnica este folosită la sistemele seriale (IBM-360, FELIX-C256).<br />
Conceptul SPOOLING (Simultaneous Peripheral Operation Off-line) s-a obţinut<br />
prin îmbinarea utilizării zonelor tampon cu conversiile off-line şi cu multiprogramarea.<br />
Sistemul funcţionează astfel: se citesc de la un cititor cartelele ce compun un job; când<br />
jobul a fost citit complet imaginile cartelelor lui sunt depuse într-un buffer pe disc - jobul<br />
se afl în starea HOLD; când CPU este liber alege unul din joburile din starea HOLD şi îl<br />
lansează în execuţie, liniile "tipărite" de către jobul în execuţie se depun într-un buffer pe<br />
disc, iar atunci când jobul a fost executat complet bufferul lui de ieşire devine disponibil<br />
pentru listare - jobul se află în starea FINISH. Operaţiile de conversie se fac în paralel cu<br />
execuţia, în regim de multiprogramare; dacă pentru execuţie sunt disponibile mai multe<br />
partiţii atunci toate au acces la cozile HOLD şi FINISH, executându-se în paralel mai<br />
multe job-uri. Simultaneitatea apare deci între joburile în curs de citire( de la cititorul de<br />
cartele), joburile în curs de execuţie( care sunt cel mult atâtea câte partiţii există) şi<br />
joburile în curs de listare.
- 7 -<br />
Cititor<br />
cartele<br />
CPU<br />
Imprimanta<br />
Execuţie on- line fără<br />
conversii<br />
Conversie<br />
intrare<br />
Conversie<br />
ieşire<br />
Conversii off-line<br />
CPU<br />
Execuţie<br />
Conversii<br />
intrare<br />
Disc<br />
magnetic<br />
Conversi<br />
i ieşire<br />
Conversii în sistem<br />
spooling<br />
Cititor cartele<br />
Imprimanta<br />
Sisteme interactive<br />
Permit comunicarea on-line dintre utilizator şi sistem. Utilizatorul dă comanda,<br />
aşteaptă răspunsul şi în funcţie de rezultatul furnizat de comanda precedentă decide<br />
asupra noii comenzi. Aceste sisteme pot fi monoutilizator sau multiutilizator<br />
Tehnica de servire time-sharing<br />
Este modul normal de servire în SO interactive multiutilizator. Fiecare utilizator<br />
are un program într-o zonă de memorie; SO comută rapid de la un program la altul<br />
înregistrând comenzile utilizatorilor (tehnica polling). CPU are viteză mare de lucru, deci<br />
într-un interval scurt fiecare utilizator este servit cel puţin o dată. Primele sisteme tip<br />
time-sharing au fost CTSS şi MULTICS. În prezent cel mai reprezentativ este sistemul<br />
UNIX.<br />
Redirectare şi legare în pipe<br />
Aplicarea acestor tehnici presupune că fiecare program are un fişier de intrare<br />
standard şi un fişier de ieşire standard.<br />
Redirectarea intrării şi/sau ieşirii standard permite înlocuirea intrării standard cu<br />
un fişier ce conţine liniile de intrare pe care le aşteaptă programul, iar liniile rezultate vor<br />
fie scoase într-un fişier oarecare sau adăugate la un unul existent.
- 8 -<br />
Informaţiile de redirectare sunt valabile din momentul lansării programului pentru<br />
care se cere aceasta şi până la terminarea lui; după terminare se revine la fişierele<br />
standard implicite.<br />
Sintactic, specificarea noilor fişiere standard de I/O se face la fel la toate SO; în<br />
linia de comandă prin care se lansează programul respectiv se vor trece numele noilor<br />
fişiere standard precedate de semnul ">" sau "
- 9 -<br />
F P1 Buffere<br />
P2<br />
Lansare P1/P2<br />
- specificarea se face astfel: P1 PRN.<br />
Avantajul acestor metode este acela că programele utilizate sunt independente de<br />
faptul că rulează sau nu în condiţii de redirectare sau pipe.<br />
Sisteme în timp real<br />
Sunt sisteme folosite pentru a dirija permanent acţiuni cum ar fi conducerea unui<br />
proces tehnologic, coordonarea unor ghişee de rezervare a locurilor etc.<br />
Un sistem în timp real poate fi definit ca un SC la care datele de intrare sunt<br />
introduse de la locul de generare a lor direct în SC, iar informaţiile de ieşire sunt<br />
transmise direct la locul de utilizare.<br />
Caracteristicile unui asemenea sistem sunt acelea că:<br />
- informaţiile din exterior sunt luate în evidenţă în momentul comunicării lor;<br />
- răspunsul SO este limitat în timp cu precizie;<br />
- timpul de execuţie al fiecărui program din sistem trebuie cunoscut dinainte.<br />
Tipuri de sisteme în timp real:<br />
- in-line: primeşte datele de intrare de la traductoare prin care se măsoară valorile<br />
unor parametri ce caracterizează procesele tehnologice; SC prelucrează datele în<br />
momentul primirii lor; rezultatele sunt transmise pe un terminal şi operatorul uman ia o<br />
decizie sau SC comandă pornirea unor dispozitive pentru corectarea parametrilor<br />
procesului;<br />
- tranzacţional: sistem interactiv; numărul şi tipul mesajelor şi comenzilor utilizate<br />
este limitat, iar formatul de citire şi afiare este fix. Aceste mesaje se numesc tranzacţii(<br />
exemplu: sistemele bancare, de rezervare a locurilor etc.).<br />
GENERAŢIA a IV-a<br />
Apare odată cu apariţia circuitelor LSI (Large Scale Integration) care permit ca un<br />
chip de siliciu de 1 cm 2 să conţină echivalentul a mii de tranzistoare.<br />
- 1969 apare primul μp( microprocesor) Intel 4004<br />
- 1975 Steve Jobs şi Stephan Wozniak construiesc primul calculator personal<br />
ALTAIR 3000<br />
- 1976 Bill Gates, Paul Allen fondează firma Microsoft, construiesc primul<br />
interpretor BASIC<br />
- 1981 IBM lansează primul calculator personal cu CPU μp Intel şi SO Microsoft<br />
Sisteme multiprocesor şi reţele de calculatoare<br />
În sistemele multiprocesor sunt conectate mai multe procesoare pentru realizarea<br />
aceleiaşi sarcini şi au acces partajat la memoria internă şi la dispozitivele periferice. De<br />
cele mai multe ori există un procesor master care controlează sistemul, lansează sau pune<br />
în aşteptare procesoarele din subordine.<br />
Există 4 tipuri de sisteme multiprocesor:<br />
1) Sisteme legate în reţea: colecţie de SC relativ autonome fiecare cu CPU,<br />
memorie şi canal I/O propriu ( şi care pot lucra sub SO diferite);
- 10 -<br />
2) Sisteme cu procesoare specializate încorporate: pe lângă CPU au încorporate<br />
procesoare specializate pe clase de operaţii (cele de I/O, calcul în virgulă flotantă ...) care<br />
sunt controlate de CPU şi folosesc aceeaşi memorie internă.<br />
Exemple- utilizarea de procesoare suplimentare (coprocesoare) pentru efectuarea<br />
anumitor tipuri de operaţii (de exemplu instrucţiuni în virgulă flotantă)<br />
- procesoare RJE (Remote Job Entry): calculatoare mici care realizează<br />
transferul joburilor către şi de la un sistem serial mare care lucrează în regim spooling.<br />
Sistemele time-sharing dispun de un calculator mic legat front-end (la aceeaşi memorie<br />
ca SC principal) pentru operaţiile I/O cu terminalele de teletransmisie legate la SC.<br />
3) Sisteme cu procesoare similare care lucrează independent: acestea<br />
partajează aceeaşi memorie internă, dar efectuează sarcinile de calcul independent; sunt<br />
subordonate aceluiaşi SO; cele mai răspândite sunt sistemele vectoriale (procesoare<br />
identice care execută aceleaşi operaţii matematice asupra elementelor unor matrici).<br />
4) Sisteme ce folosesc procesoare paralele: acestea cooperează între ele<br />
efectuând sarcini de calcul ale aceluiaşi job. Algoritmul de rezolvare a unei probleme este<br />
descompus în secvenţe ce pot fi tratate în paralel (timpii de execuţie nu coincid ca la cele<br />
vectoriale); lansarea unei secvenţe aşteaptă până când s-au terminat toate secvenţele ce<br />
trebuiau să îi succeadă.<br />
Altă clasificare a sistemelor multiprocesor des utilizată este următoarea:<br />
1) Sisteme SISD( Single Instruction-Single Data) - arhitectură clasică, von Neumann<br />
2) Sisteme SIMD( Single Instruction Multiple Data) - procesoare vectoriale<br />
3) Sisteme MISD(Multiple Instructions Single Data) -rar folosite, datele trebuie protejate;<br />
4) Sisteme MIMD( Multiple Instructions Multiple Data) – sunt procesoarele paralele.<br />
1.1.3. Structura şi componentele unui SC<br />
Structura şi funcţiile hard. Există 4 clase de componente hard, indiferent de<br />
tipul SC: - unitatea de memorie care execută operaţii de memorare şi regăsire a<br />
informaţiilor;<br />
- componenta de prelucrare;<br />
- periferice de intrare-ieşire;<br />
- componenta de control.<br />
Memoria. Este o succesiune de dispozitive logice elementare, fiecare fiind<br />
capabil să reţină una dintre valorile 0 sau 1 numite biţi. Biţii sunt organizaţi într-un şir şi<br />
grupaţi în unităţi de memorare numite octeţi. Se fac trei ipoteze asupra memoriei:<br />
1) Fiecare octet are acelaşi număr de biţi;<br />
2) Fiecare octet se referă în mod unic printr-un număr numit adresa octetului;<br />
3) Memoria este volatilă: după terminarea unui program se pierde conţinutul<br />
octeţilor asupra cărora s-a acţionat.<br />
Funcţional există două tipuri de memorii: memorie ROM( Read Only Memory)<br />
din care se pot doar citi date şi memorie RAM( Random Access Memory) în care se pot<br />
şi scrie date.<br />
Componenta de prelucrare: are posibilităţi de a manipula un număr finit de<br />
date( bit, octet, întreg, real...) cu ajutorul unor operaţii primare care sunt instrucţiuni<br />
maşină. Realizarea instrucţiunilor se face pe baza unor circuite electronice din
- 11 -<br />
microprocesor (instrucţiuni hard) la care se adaugă rutine programate de către firma<br />
constructoare ( şi depuse în ROM).<br />
Principiul fundamental al SC actuale este acela că se execută un program ale cărui<br />
instrucţiuni se află împreună cu datele în memoria internă a SC.<br />
Periferice: din punct de vedere funcţional se împart în periferice de schimb cu<br />
mediul extern: cititor cartele, imprimantă, terminale de teletransmisie, plottere, ...<br />
respectiv purtătoare de informaţii permanente pe medii magnetice: benzi magnetice,<br />
tamburi magnetici, suporturi în acces direct de tip disc.<br />
Dintr-o altă perspectivă perifericele sunt de tip bloc sau de tip caracter.<br />
Periferice bloc: memorează informaţia în blocuri de lungime fixă, fiecare bloc<br />
având propria adresă (conţine în general 128, 512 sau 1024 octeţi); un bloc poate fi scris<br />
sau citit indiferent de celelalte; mediile de tip disc sunt cele mai importante dintre<br />
perifericele de tip bloc. Blocul de informaţii este unitatea de schimb între perifericele<br />
bazate pe suporturi magnetice şi memoria internă. Un bloc de informaţii conţine pe lângă<br />
succesiunea propriu-zisă de octeţi un număr suplimentar de octeţi şi biţi destinaţi<br />
verificării corectitudinii informaţiei memoriei în blocul respectiv.<br />
Perifericele de tip caracter: furnizează sau acceptă un flux de octeţi fără<br />
structură de bloc; octeţii din grup nu sunt adresabili şi fiecare octet este disponibil ca şi<br />
caracter curent doar până la apariţia următoare. Exemple de astfel de periferice sunt<br />
cititorul cartele, banda de hârtie perforată, imprimanta, terminale cu tastatur şi ecran,<br />
mouse.<br />
Componenta de control împreună cu cea de prelucrare şi cu sistemul de<br />
întreruperi formează unitatea centrală de prelucrare CPU.<br />
1.1.4. Arhitectura unor SC interactive<br />
Arhitectura minicalculatoarelor compatibile PDP<br />
Apar în 1970, construite de firma DEC (Digital Equipament Corporation). Cele<br />
mai răspândite sunt cele din familia PDP-11 (mai ales seriile 11/34A, 11/44, 11/70 după<br />
1979). In România, din 1977 se utilizează familiile Independent şi CORAL.<br />
Arhitectura hard a unui minicalculator compatibil PDP este următoarea:<br />
CPU<br />
PAR0<br />
PAR1<br />
PAR2<br />
PAR3<br />
PAR4<br />
PAR5<br />
PAR6<br />
PAR7<br />
PVF<br />
ALU<br />
R0<br />
R1<br />
R2<br />
R3<br />
R4<br />
R5<br />
R6( SP)<br />
R7( PC)<br />
BUS<br />
Control<br />
Bus<br />
Memorie<br />
TT: DP: DK: MM: DX: CR: LP:<br />
TT1:…TTn:
- 12 -<br />
CPU execută toate operaţiile logice şi aritmetice şi conţine:<br />
ALU: operaţii aritmetice în virgulă fixă pe 16 biţi<br />
PVF: procesor pentru calcule în virgulă flotantă<br />
DMM: dispozitiv de management al memoriei<br />
registre generale: capacitate 16 biţi,dublu exemplar (unul pentru monitorsuperior,<br />
altul pentru utilizator), R6 conţine Stack Pointer, R7 - Program Counter, pot fi<br />
folosiţi ca acumulatori, indicatori de adrese, regiştri de indecşi.<br />
Mecanismul de adresare<br />
Memoria are o capacitate de 4Mo; consecinţă a lungimii cuvântului maşină un<br />
program poate adresa 64Ko; Dispozitivul de Management al Memoriei (DMM) permite<br />
creşterea spaţiului de adresare la 4Mo. În momentul în care el este activat, adresa de 16<br />
biţi nu mai este folosită ca adresă fizică ci ca adresă virtuală care conţine informaţia<br />
necesară constituirii adresei fizice de 22 biţi. Mecanismul de constituire a adresei fizice<br />
este următorul:<br />
P<br />
AV:<br />
21 6<br />
AFP<br />
15 13 12 6 5 0<br />
P NB<br />
DB<br />
+<br />
PAR 0-7<br />
AF:<br />
21 6 5 0<br />
AFP+ NB<br />
DB<br />
AV se reprezintă pe 16 biţi şi este formată din:<br />
- număr pagină P,<br />
- număr bloc în pagină NB,<br />
- deplasament în cadrul blocului DB<br />
- programele executabile se împart în pagini cu lungimea maximă de 2 13 octeţi,<br />
adresa de încărcare a fiecărei pagini este multiplu de 2 6 , rezultă că pentru adresa de<br />
încărcare a fiecărei pagini se folosesc 13 biţi dintre care primii 6 (cei mai puţin<br />
semnificativi) sunt 0. Fiecare program executabil poate opera cu maximum 8 pagini<br />
rezultă 3 biţi pentru numărul paginii, biţii 13-15 ai adresei virtuale;<br />
- fiecare pagină se împarte în maxim 2 7 blocuri de lngimea 2 6 , fiecare bloc începe<br />
la o adresă multiplu de 2 6 rezultă că numărul blocului în cadrul paginii se poate scrie pe 7<br />
biţi 6-12<br />
- adresa unui octet în cadrul blocului se scrie pe 6 biţi, biţii 0-5.<br />
În DMM există 8 regiştri de adrese ale unor pagini din memoria operativă (pagini<br />
fizice, reale), PAR0 - PAR7. O pagină se află la multiplu de 2 6 rezultă că cei 6 biţi<br />
nesemnificativi din adresa reală a începutului de pagină sunt 0. De aceea regiştrii au 16<br />
biţi fiecare pentru a materializa biţii 6-12 din adresa de început a paginii fizice.<br />
La încărcarea programului în memorie, paginile virtuale ale lui sunt plasate în<br />
zonele de memorie liberă, la adrese multipli de 2 6 , iar aceste adrese sunt plasate în<br />
registru PAR corespunzător. Când DMM primeşte o adresă virtuală pe 16 biţi o
- 13 -<br />
transformă în adresă reală adunând conţinutul registrului PAR indicat de P cu câmpul NB<br />
al adresei virtuale, după care rezultatului i se concatenează câmpul DB din adresa<br />
virtuală. DMM asigură şi protecţia paginii fizice între utilizatori: pe lângă fiecare registru<br />
PAR există un registru PDR (registru descriere pagină) ce conţine lungimea paginii, dacă<br />
în ea s-a scris sau nu, în ce direcţie se poate extinde pagina şi ce drepturi de acces sunt<br />
permise asupra ei. Unele SC dispun şi de componenta PVF ce realizează operaţii în<br />
virgulă mobilă.<br />
Sistemul de intrare/ieşire<br />
Toate comunicaţiile între modulele SC se realizează prin intermediul unei<br />
magistrale unice de informaţii BUS ce permite un trafic de 10Mo/SC; comunicarea pe<br />
BUS între 2 module se face în regim master-slave: la un moment dat un modul<br />
controlează BUS-ul (master) şi un alt modul (slave) este controlat de BUS; în timp ce un<br />
modul execută un ciclu de operare pe BUS altul poate obţine pentru tactul următor<br />
dreptul de a opera pe BUS; sarcina arbitrajului revine (în caz de conflicte) componentei<br />
controlor de BUS.<br />
Arhitectura microcalculatoarelor pe 8 biţi<br />
Au la bază microprocesorul, care apare în 1970 şi se dezvoltă masiv după 1980.<br />
Există microprocesoare pe 8 biţi, 16 biţi, 32 biţi ...<br />
Structura unui microcalculator pe 8 biţi este următoarea:<br />
CPU( I8080 sau Z80)<br />
DB<br />
Date<br />
Memorie<br />
ROM<br />
A<br />
ALU<br />
B<br />
D<br />
H<br />
IX<br />
IY<br />
SB<br />
PC<br />
AB<br />
C<br />
E<br />
L<br />
Adrese<br />
RAM<br />
PUN: RDR: LST: A: B: C: D: CON:<br />
În domeniul realizării microprocesoarelor pe 8 biţi pe primul loc se află firma<br />
ZILOG cu Z80 urmată de Intel cu I8080, aceste două microprocesoare fiind compatibile.<br />
Exemple de microcalculatoare cu microprocesor pe 8 biţi: FELIX-M18, M18B,<br />
M118, M118B din 1979, CUB (cu I8080) şi CUBZ (cu Z80), aMIC, TIM-S<br />
Nucleul CPU este format din microprocesor I8080 sau Z80, capabil să execute<br />
127 instrucţiuni maşină: operaţii aritmetice, logice, deplasări, cereri I/O etc. Are
- 14 -<br />
următoarele unităţi funcţionale:<br />
- zona registrului de date şi adrese conţine: numărător de adrese al progr., PC, de 16 biţi,<br />
pointer stiva SP, registru de date de 8 biţi DB, registru adrese de memorie de 16 biţi AB;<br />
- 6 regiştri generali de câte 8 biţi B,C,D,E,F,H,L ce pot fi folosiţi individual sau perechi;<br />
- 2 regiştri de indecşi IX, IY<br />
- unitatea aritmetico-logică ce are un registru acumulator pe 8 biţi, A;<br />
- o magistrală de date BUS pe 8 biţi.<br />
Organizarea memoriei:<br />
1) zona ROM: conţine monitorul calculatorului,<br />
2) zona RAM: între 32KO şi 64KO la dispoziţia utilizatorului<br />
- mecanismul de adresare: adresele din program coicid cu cele fizice şi se<br />
reprezintă pe 16 biţi.<br />
Subsistemul de I/O este formar din: consola; imprimanta LST; unitatea de bandă<br />
sau casetă magnetică (ca intrare standard RDR:); unitatea de bandă sau casetă ca ieşire<br />
standard( PUN:); cel mult 4 unităţi de disc flexibil( A: B: C: D:). În acest caz nu se poate<br />
realiza în mod direct paralelismul între acţiunea CPU şi operaţiile I/O.<br />
Arhitectura microcalculatoarelor pe 16 biţi<br />
Aceste calculatoare folosesc drept CPU un microprocesor pe 16 biţi. Piaţa<br />
microcalculatoarelor pe 16 biţi este dominată de IBM.<br />
- 1979 - primul microprocesor pe 16 biţi, 8086<br />
- 1981 – apare 8088 cu frecvenţă de 4 MHz – pe baza lui s-au construit primele<br />
IBM-PC şi IBM-PC XT dotat cu facilităţi hard suplimentare<br />
- 1982 - 80186 (mică extensie a lui 8086) şi 80286 care extinde mult 8086:<br />
frecvenţa lui este de 6MHz, are instrucţiuni maşină în plus şi extinde modul de adresare.<br />
Stă la baza celor mai multe tipuri de IBM-PC<br />
- 1985 - 80386, microprocesor pe 32 biţi la 20 MHz<br />
- 1989 - 80486, 33 MHz, are instrucţiuni de calcul în virgulă flotantă; creşte<br />
randamentul de 2,5 ori.<br />
Structura unui microprocesor pe 16 biţi este următoarea:<br />
CPU( I8086, 80286, 80386) COPM Memorie<br />
AH<br />
BH<br />
CH<br />
DH<br />
SP<br />
BP<br />
DI<br />
SI<br />
AL<br />
BL<br />
CL<br />
DL<br />
CS<br />
DS<br />
SS<br />
ES<br />
IP<br />
ADR<br />
8087<br />
80287<br />
80387<br />
Adrese<br />
ROM<br />
EXTRAM<br />
RAM<br />
Date<br />
EU<br />
ALU<br />
1 2 3 4 5 6<br />
BIU<br />
PRN: A:, B: C:, D: CON:
- 15 -<br />
Organizarea microprocesorului:<br />
Componenta EU (Executive Unit):<br />
- unitate aritmetico-logică ALU ce operează pe 16 biţi<br />
- 4 registre generale de 16 biţi AX, BX, CX, DX fiecare împărţite în 2 registre de<br />
8 biţi; AH, BH, CH, DH conţin biţii cei mai semnificativi; AX este acumulatorul general,<br />
BX registrul de bază, CX registrul numărător, iar DX registrul de date;<br />
- registrul SP - indicator la sfârşitul stivei, CP registrul de bază al stivei, SI, DI<br />
regiştri de index pentru operaţiile sursă respectiv destinaţie dintr-o instrucţiune maşină.<br />
Componenta BIU (BUS Interface Unit): se ocupă de calculele de adresă şi de<br />
prima etapă din execuţia unei instrucţiuni (citirea codului instrucţiunii, decodificarea<br />
instrucţiunii, citirea operaţiilor din memorie, restul face EU).<br />
O instrucţiune se reprezint pe 1-6 octeţi; componentele EU şi BIU cooperează<br />
printr-un mecanism pipe: în BIU există o zonă tampon de 6 octeţi în care se află<br />
instrucţiunile ce urmează a se executa (în timp ce instrucţiunea curentă este executată de<br />
către EU).<br />
Mecanismul de adresare<br />
Calculele de adrese se fac de către BIU prin intermediul unităţii de calcul<br />
specifice ADR şi a regiştrilor CS, DS, SS, ES de câte 16 biţi.<br />
Memoria SC de acest tip este de 1MO: primele 16 blocuri a câte 64 KO formează<br />
memoria RAM; urmează 5 blocuri a câte 64 KO pentru memoria ecran şi pentru a reţine<br />
conţinutul memoriei ROM în timpul funcţionării sistemului.<br />
O adresă se reprezintă pe 20 biţi (2 20 = 1 MO), aceasta este capacitatea magistralei<br />
de adrese; magistrala de date are capacitatea de 16 biţi.<br />
Cum se obţine o adresă de 20 biţi folosind cuvinte de 16 biţi?<br />
Orice program utilizabil este compus din 4 tipuri de segmente:<br />
- segment de cod ce conţine instrucţiuni maşină;<br />
- segment de date ce conţine date asupra cărora se acţionează;<br />
- segment de stivă pentru legătura între programe-apelatoare şi subrutine apelate<br />
- segmente suplimentare (extrasegmente)<br />
corespunzător sunt ataşaţi unul din registrele de segment CS, DS, SS, ES.<br />
Prin convenţie, adresa de început a fiecărui segment este multiplu de 2 4 (rezultă că<br />
primii 4 biţi, cei mai nesemnificativi ai adresei de început de segment vor fi 0, deci<br />
regiştrii de segment au numai 16 biţi ce conţin biţii 4-19 ai adresei de început a<br />
segmentului). Un segment poate avea cel mult 2 16 octeţi rezultă că pentru a specifica<br />
deplasamentul în cadrul segmentului (OFS), BIU calculează adresa fizică astfel:<br />
AF= CRS 2 4 + OFS ( înmulţire cu 2 4 înseamnă deplasare cu 4 biţi spre stânga)<br />
De exemplu, dacă CRS= 7BC1, OFS= 54A3 atunci<br />
AF= 7BC1* 2 4 + 54A3= 7BC10+ 54A3= 810B3.<br />
Acest mecanism de adresare este tipic pentru 8086 şi se numeşte mod real (Real<br />
Virtual Address Mode)<br />
Începând cu 80386 mai apar 2 moduri de adresare: paginată şi virtuală (pentru a<br />
permite adresarea a mai mult de 1MO).<br />
Sistemul de intrare/ieşire<br />
Conţinutul memoriei ROM este înscris în momentul fabricării SC şi nu poate fi<br />
modificat. Cea mai mare parte a memoriei ROM o formează componenta ROM-BIOS<br />
care oferă rutine de I/O comode. Prin distribuirea surselor de specificare pentru BIOS,
- 16 -<br />
IBM a impus un standard hard/soft ce constă în apeluri BIOS, locaţii de memorie, adrese<br />
de periferice rămase aceleaşi şi azi. Rutinele BIOS nu sunt întreruptibile (pentru sisteme<br />
multiutilizator, în special UNIX, se rescriu unele rutine din BIOS).<br />
Principalele tipuri de dispozitive periferice legate la SC de tip IBM-PC sunt:<br />
- consola: terminal legat la memorie ecran printr-un adaptor video<br />
- imprimanta<br />
- cel puţin o unitate de disc flexibil<br />
- una sau două unităţi de disc dur( Winchester).<br />
1.1.5. Istoricul unor SO interactive<br />
SO RSX<br />
Are ca reprezentant principal sistemul RSX -11M conceput de firma DEC pentru<br />
minicalculatoare din seria PDP-11. Este orientat pentru lucrul în timp real, dar permite<br />
dezvoltarea de programe pentru multe limbaje de programare. În România, în 1978 apar<br />
două SO compatibile RSX elaborate de ITCI Bucureşti: SO AMS şi SO MINOS; până la<br />
un anumit nivel erau compatibile între ele şi compatibile cu RSX, dar comenzi cu<br />
aceleaşi funcţii aveau nume diferite şi au aprut confuzii. In 1983-1984 se reunesc<br />
funcţiile celor două SO şi apare SO MIX care funcionează şi azi în paralel cu RSX.<br />
SO UNIX<br />
In 1968 Ken Thompson de la Bell Labs, în timp ce lucra la implementarea SO<br />
MULTICS, îşi pune problema elaborării unui sistem simplu de manipulare a fişierelor la<br />
SC PDP-7. Împreună cu Dennis M.Ritchie creează sistemul UNIX. In 1969 apare prima<br />
versiune a SO UNIX scris în limbaj de asamblare, iar în 1970 versiunea a doua. In 1972<br />
Dennis M. Ritchie proiectează limbajul de programare "C" şi în urma acestui fapt, în<br />
1973 apare versiunea a treia UNIX scris aproape exclusiv în "C"; textul sursă al SO<br />
conţine 10-15000 linii sursă în "C", deci limbajul de programare este de nivel înalt cu<br />
portabilitate ridicată şi cel mul 1000 linii necesare a fi scrise în limbajul de asamblare al<br />
maşinii pe care se implementează SO UNIX. Prima implementare industrială se face pe<br />
PDP-11/45, iar firma Bell (AT& T Bell Laboratories) obţine drept de licenţă asupra lui<br />
UNIX şi îl livrează gratuit universităţilor asigurându-I astfel popularitatea. In 1978 apare<br />
versiunea a şaptea, îmbunătăţită prin contribuţia universităţii Berkeley – California. In<br />
1984 AT & Bell creează UNIX SYSTEM V; firma Microsoft cumpără licenţa sistemului<br />
de la AT & T, fără drept de utilizare a numelui UNIX. Microsoft numeşte aceast<br />
implementare XENIX. În ultimii ani au apărut mai multe implementări de reţele de<br />
calculatoare care funcţionează sub UNIX, utilizând protocoale care devin standard (ex.<br />
TCP/IP, TELNET). UNIX este acum sistem de referinţă în sistemele de operare.<br />
SO CP/M (Control Program for Microcomputers)<br />
Este un SO rezident pe disc flexibil pentru dezvoltarea de programe în monoacces<br />
conversaţional, operaţional pe microcalculatoare ce folosesc microprocesoare pe 8 biţi<br />
(Z80, I8080) şi care au în configuraţie unităţi de disc flexibil. A fost proiectat de<br />
G.Kildall care îl propune spre omologare firmei Intel în 1973; aceasta refuză. Sistemul<br />
este omologat de Digital Research Co., în 1981 are loc o răspândire masivă a sistemului;<br />
IBM Xerox, HP îl preiau i-l implementează pe calculatoarele lor de 8 biţi.<br />
In România, primul microcalculator pe 8 biţi a fost FELIX-M18; a funcţionat întâi<br />
sub SO SFDX-18, apoi sub CP/M care a fost implementat apoi pe toate calculatoarele de
- 17 -<br />
8 biţi (M18, TDP, JUNIOR, M216, CUBZ). Există o variantă a sistemului şi pe 16 biţi,<br />
CP/M-86 Şi dezvoltări pentru CP/M multiutilizator şi CP/M în reţea.<br />
SO MS-DOS<br />
A fost comandat în 1979 de către IBM firmei Microsoft; IBM îl modifică şi-l<br />
numeşte PC-DOS. MS-DOS a fost lansat în 1981 odată cu primul IBM-PC. Este un<br />
sistem monoutilizator, monotasking cu interfaţă simplă între utilizator şi hard.<br />
Istoric:<br />
- 1981 versiunea 1: are la bază CP/M; se pot adresa 640 KO memorie; gestionează<br />
dischete de 5,25" cu capacitate de 320 KO;<br />
- 1983 vers. a doua: permite gestionarea dischetelor de 5,25" cu 360 KO şi a discurilor<br />
dure cu maximum 32 MO; sunt introduse direct cu structura de arbore din UNIX;<br />
- 1985 versiunea a treia poate lucra cu dischete de 3,5", permite gestiunea releelor locale<br />
cu partajarea resurselor între utilizatori;<br />
- în versiunea a patra apar incompatibilităţi cu versiunile anterioare;<br />
- 1990 vers. a cincea: funcţionează pe orice tip de PC. În prezent există versiunea 6.22.<br />
Firma Digital Research creează DR-DOS, până la versiunea a şasea, mai bune ca<br />
DOS în unele aspecte.<br />
Sub DOS apare o suprafaţă utilizator, extensie a SO-DOS numită WINDOWS<br />
utilizabilă la PC cu microprocesor 80386, cel puţin 384 KO memorie şi disc dur.<br />
1.2. Structura şi funcţiile sistemelor de operare<br />
1.2.1. Tipuri de SO; clasificări<br />
Se vor prezenta clasificări ale SO în funcţie de următoarele criterii:<br />
a) după configuraţiile hard pe care le deservesc<br />
b) după gradul de portajabilitate a resurselor;<br />
c) după tipurile de interacţiuni permise<br />
d) după organizarea internă a programelor ce compun SO<br />
a) Clasificarea după configuraţiile hard pe care le deservesc<br />
1) SO pentru microcalculatoare: deservesc microcalculatoare pe 8, 16 şi 32 biţi;<br />
sunt sisteme simple; sarcinile pe care le îndeplinesc sunt: punerea în lucru la pornirea SC,<br />
schimburi între memoria internă şi periferice, gestiunea unui sistem de fişiere capabil să<br />
manipuleze un număr mare de fişiere de dimensiuni mici; sunt de tip monoutilizator, dar<br />
se pot lega în reţele sau se pot conecta la sisteme mari fiind privite ca posturi de lucru.<br />
2) SO pentru minicalculatoare: ţinand cont de faptul că cele mai multe<br />
minicalculatoare azi sunt SC interactive multiutilizator SO au în vedere partajarea<br />
resurselor, planificarea CPU pentru servirea utilizatorilor etc. (se lucrează de obicei în<br />
time-sharing şi multiprogramare).<br />
3) SO pentru calculatoare medii-mari (main-frame computers): aceste tipuri<br />
de SC suportă atât modul de lucru serial cât şi interactiv, sunt puternice, au dimensiuni<br />
mari ale cuvintelor de memorie(până la 64 biţi) şi au conectate un nr. mare de periferice.<br />
b) După gradul de partajabilitate a resurselor
- 18 -<br />
1) SO monoutilizator: la aceste SO la un moment dat se execută un singur<br />
program şi acesta rămâne activ din momentul lansării în execuţie până la terminarea lui;<br />
la sisteme mari se aplică tehnica swapping, evacuarea temporară a unui program din<br />
memoria internă pe disc magnetic, în acest timp în memoria internă este încărcat alt<br />
program care este executat parţial... (cât timp un program este în memorie el are acces la<br />
toate resursele sistemului).<br />
2) SO multiutilizator: trebuie să aibă în vedere partajarea memoriei, a timpului, a<br />
perifericelor etc. între utilizatorii activi (la un moment dat există mai multe procese active<br />
care se execută concurent).<br />
c) După tipurile de interacţiuni permise<br />
1) Sisteme seriale: lucrările se execută pe loturi gata pregătite; utilizatorul nu<br />
poate interveni.<br />
2) Sisteme interactive: în funcţie de rezultatele intermediare utilizatorul poate<br />
decide modul de continuare a activităţii proprii; SO trebuie să gestioneze şi terminalele<br />
de teletransmisie la care se află utilizatori.<br />
3) Sisteme în timp real: SO trebuie să deservească în timp prestabilit fiecare<br />
serviciu ce i se cere.<br />
Acest criteriu de clasificare este relativ: există sisteme seriale ce permit<br />
interacţiunea cu programele; sisteme interactive cu facilităţi de lucru serial etc.; există SC<br />
care pot lucra în timp real şi să deservească în acelasi timp( cu prioritate mai mică) alte<br />
programe de tip serial sau interactiv în regim de multiprogramare clasică.<br />
d) După organizarea internă a programelor SO<br />
1) Sisteme monolitice: SO este o colecţie de proceduri cu proprietatea că<br />
execuţia unei proceduri nu poate fi întreruptă; programul utilizatorului se comportă ca o<br />
procedură apelată de SO; programatorii pot apela în maniera apelurilor sistem rutine ale<br />
SO. Esenţială este legătura de tip apel-revenire fără posibilitatea de întrerupere a fluxului<br />
normal de execuţie.<br />
2) Sisteme cu nucleu de interfaţă hardware: concentrează sarcinile de nivelul<br />
cel mai apropiat de hard într-o colecţie de rutine ce formează nucleul SO, componentele<br />
nucleului se pot executa concomitent. Toate acţiunile utilizatorului asupra echipamentului<br />
hard trec prin nucleu. Exemple de nucleu: BIOS sub CP/M şi MS-DOS.<br />
3) Sisteme cu structură stratificată: sunt generalizări ale celor cu nucleu. SO<br />
este construit nivel după nivel, componentele fiecărui nivel foloseşte serviciile oferite de<br />
nivelul inferior. Sunt cele mai răspândite SO, "părinţii" acestor sisteme sunt SO THE şi<br />
SO MULTICS.<br />
4) Sisteme organizate ca maşini virtuale: echipamentul hard serveşte în regim<br />
de multiprogramare( sau time-sharing) mai multe procese. Fiecare proces dispune în mod<br />
exclusiv de resurse (în principal memorie). Fiecare dintre procesele deservite este un SO<br />
ce are la dispoziţie toate resursele alocate procesului respectiv de către echipamentul<br />
hard. În acest mod, pe acelaşi echipament hard se poate lucra sub mai multe SO simultan.<br />
Tipic este SO VM/370 (Virtual Machines for IBM-370) care coordonează mai multe SO<br />
conversaţionale monoutilizator de tip CMS (Conversational Monitor System); fiecare<br />
utilizator lucrează sub propriul CMS. Conceptul de programare orientată obiect<br />
contribuie la dezvoltarea de SO sau componente de SO organizate ca maşini virtuale<br />
(similitudine între obiect şi maşină virtuală).
- 19 -<br />
1.2.2. Structura şi funcţiile generale ale SO<br />
Funcţiile SO<br />
Principala menire a unui SO este pe de o parte de a facilita accesul utilizatorului<br />
la sistem, iar pe de altă parte exploatarea eficientă a echipamentelor de calcul.<br />
O noţiune ce va fi des utilizată în continuare este noţiunea de proces . Un proces<br />
(task) este un calcul ce poate fi efectuat concurent cu alte calcule( noţiunea se va utiliza si<br />
în loc de program)<br />
Obiectivele fundamentale ale SO sunt<br />
a) optimizarea utilizării resurselor;<br />
b) minimizarea efortului uman de programare şi utilizare;<br />
c) automatizarea operaţiilor manuale în etapele de pregătire şi exploatare a SC;<br />
d) creşterea eficienţei utilizării SC prin scăderea costului de prelucrare a datelor;<br />
Pentru a evidenţia funcţiile SO se vor analiza stările în care se poate afla un<br />
proces gestionat de SO şi acţionarea acestuia pentru tranziţia între diversele stări ale<br />
procesului.<br />
Prezentare<br />
Conversie de intrare,<br />
eventual prin<br />
SPOOLING<br />
Rezolvare<br />
întrerupere,<br />
terminare I/O<br />
Eliberare<br />
procesor<br />
HOLD<br />
READY<br />
Alocare<br />
procesor la<br />
proces<br />
Alocare memorie<br />
Creare proces<br />
Alocare periferice( fişiere)<br />
Alocare memorie<br />
Reîncărcare<br />
Eliberare spaţiu disc<br />
WAIT<br />
Lansare operaţie<br />
Eliberare procesor<br />
RUN<br />
Eliberare procesor,<br />
periferice, memorie<br />
Ştergere proces<br />
SWAP<br />
Ocupare spaţiu disc<br />
Evacuări<br />
Eliberare memorie şi<br />
procesor<br />
Convenţi de ieşire,<br />
eventual prin SPOOLING<br />
FINISH<br />
Eliberare
- 20 -<br />
Structura generală a unui SO<br />
Se va prezenta un SO ipotetic. La SO reale unele dintre componente vor fi<br />
"atrofiate", altele pot fi mai dezvoltate. Iată câteva definiţii utile:<br />
SO - set de proceduri manuale şi automate ce oferă unui grup de utilizatori<br />
posibilitatea să folosească în acelaşi timp şi eficient sistemul de calcul.<br />
Operator uman - persoana care colaborează cu SO pentru desfăşurarea activităţii<br />
SC.<br />
Utilizator - persoană ce foloseşte SC; în sistemele seriale SO nu-l consultă la<br />
executarea programului, în cele interactive poate interveni.<br />
Job - colecţie de activităţi necesare execuţiei unei lucrări.<br />
Faza- este o subunitate a jobului. Este acceptată ca tip de fază una dintre<br />
următoarele activităţi:<br />
- editarea unui text;<br />
- compilarea unui program;<br />
- editarea de legături;<br />
- execuţia unui program;<br />
- depanarea asistată de calculator a unui program.<br />
Structura generală a unui SO este următoarea:<br />
P S<br />
A E<br />
R R<br />
T V<br />
E I<br />
C<br />
I<br />
I<br />
P<br />
A<br />
R<br />
T<br />
E<br />
C<br />
O<br />
N<br />
T<br />
R<br />
O<br />
L<br />
Medii de<br />
programare<br />
Utilitare<br />
Interpretoare<br />
Biblioteci de<br />
programe<br />
Macroprocesoare<br />
Gestiune<br />
tehnică<br />
SO<br />
Baze de date<br />
Editoare de<br />
texte<br />
Alte aplicaţii<br />
Rutine de<br />
depanare<br />
Compilatoare Asambloare Link-editoare Loadere<br />
Gestiune<br />
tehnică<br />
SO<br />
UTILIZATOR<br />
Suprafeţe de operare<br />
Planificare lucrări şi alocare resurse<br />
Întreruperi<br />
Gestiune fişiere<br />
I/O la nivel fizic<br />
Gestiune memorie<br />
Gestiune<br />
procese<br />
HARD<br />
Dispecer<br />
procesoare<br />
Bibliotecar<br />
Gestiune<br />
economică<br />
SO
- 21 -<br />
PARTEA DE CONTROL A UNUI SO: este partea aflată în legătură directă cu<br />
operatorul uman şi indirectă cu utilizatorul. Componentele ei sunt executate în mod<br />
master, iar principalul ei rol este de a realiza legătura cu echipamentul hard.<br />
Întreruperi: ansamblu de rutine, fiecare fiind activată la apariţia unui semnal<br />
fizic de întrerupere; corespunzător SO efectuează acţiunile aferente întreruperii<br />
respective.<br />
Mecanismul de funcţionare a unei întreruperi este următorul( presupunem că<br />
execuţia unei instrucţiuni maşină nu poate fi întreruptă):<br />
- starea unui program la un moment dat( PSW) este perechea formată din:<br />
a) adresa următoarei instrucţiuni de executat;<br />
b) conţinutul tuturor regiştrilor maşină la terminarea ultimei instrucţiuni<br />
- fiecare sursă posibilă a unei întreruperi are asociată o locaţie fixă de<br />
memorie în care se află o adresă care indică locul în memorie în care se află<br />
secvenţa de instrucţiuni (numită handler) ce deserveşte întreruperea;<br />
- la apariţia semnalului de întrerupere se execută în ordine următoarele activităţi:<br />
- se salvează în memorie( în stivă sau într-o zonă specială) PSW al<br />
programului în curs de desfăşurare;<br />
- se restaurează PSW al handlerului asociat întreruperii;<br />
- handlerul execută acţiunea pentru revenirea întreruperii;<br />
- se salvează PSW al handlerului;<br />
- se salvează PSW al programului întrerupt;<br />
Gestiune procese: creează procese, se ocupă de cooperarea şi concurenţa între<br />
ele, şterge procesele din sistem la terminarea lor.<br />
Dispecer procesoare: la sistemele multiprocesor repartizează sarcinile de calcul<br />
solicitate de procese procesoarelor libere.<br />
Gestiunea memoriei: alocă memorie internă proceselor şi asigură protecţia<br />
memoriei interprocese.<br />
I/O la nivel fizic: asigură desfăşurarea operaţiilor de I/O elementare cu toate<br />
perifericele din sistem realizând, dacă se poate, paralelismul cu activitatea procesorului<br />
central; este o componentă dependentă hard, compatibilitatea cu sistemul este realizată de<br />
drivere.<br />
Gestiunea fişierelor: colecţie de module pentru deschidere, închidere şi acces la<br />
fişierele de pe diferite suporturi, este componenta cel mai des folosită de utilizator.<br />
Planificarea lucrărilor şi alocarea resurselor: resursele sistemului sunt resurse<br />
fizice ( procesoare, memorie internă, periferice) şi resurse logice ( proceduri comune,<br />
tabele sistem, ...); acest compartiment asigură planificarea proceselor astfel încât ele să<br />
poată obţine resursele necesare individual sau partajat cu alte procese.<br />
Gestiunea tehnică a SO: ţine evidenţa erorilor hard i furnizează informaţii<br />
statistice asupra gradului de utilizare a componentei SC.<br />
Gestiunea economică: ţine evidenţa utilizatorilor, lucrările executate de către<br />
aceştia, resursele consumate, ...<br />
PARTEA DE SERVICII<br />
Compilatoarele: programe ce traduc texte sursă din limbaje de nivel înalt în<br />
limbaj maşină; rezultatul compilării este un modul obiect.
- 22 -<br />
Asamblorul: program ce traduce texte scrise în limbaj de asamblare în limbaj<br />
maşină.<br />
Link-editorul: grupează unul sau mai multe module obiect împreună cu<br />
subprograme de serviciu din biblioteci, în programe executabile; oferă posibilitatea<br />
segmentării.<br />
Loader: este un program care are ca sarcini:<br />
- citirea unui program executabil pe un suport;<br />
- încărcarea programului în memorie;<br />
- lansarea programului în execuţie;<br />
- dacă programul este segmentat se încarcă doar segmentul rădăcină.<br />
Interpretor: program ce execută pas cu pas instrucţiunile descrise într-un anumit<br />
limbaj. Există două tipuri de interpretoare:<br />
- interpretoare pentru limbaje ca BASIC, PROLOG, LISP<br />
- interpretoare de comenzi.<br />
Macroprocesor: program ce transformă o machetă de program pe baza unor<br />
parametri, într-un program sursă compilabil.<br />
Exemplu: dacă se scrie următoarea machetă:<br />
MACRO ADUNA &1, &2, &3<br />
LOAD &1<br />
ADD &2<br />
STORT &3<br />
ENDMACRO<br />
atunci la apelare prin ADUNA A,B,C se execută calculul C:=A+B.<br />
Aceeaşi metodă se aplică şi la scrierea parametrizată a unei succesiuni de comenzi ale<br />
SO.<br />
Editor de texte: program interactiv pentru introducerea şi corectarea de texte.<br />
Rutine de depanare: asistă execuţia programului utilizatorului şi-l ajută să<br />
depisteze cauzele erorilor apărute în timpul execuţiei. La apariţia în execuţie a unui<br />
eveniment deosebit( depăşiri indici, adresă inexistentă, cod operaţie necunoscut)<br />
controlul se dă depanatorului. Acesta mai poate primi controlul în locuri marcate de către<br />
utilizator( breakpoint). La primirea controlului depanatorul poate afişa valorile de<br />
variabile sau locaţii de memorie, poate afişa parţial sau total istoria de calcul.<br />
- tipuri de depanatoare:<br />
- maşină: operează cu adrese fizice, locaţii de memorie, configuraţie de<br />
biţi; fiecare SO dispune de asemenea depanator;<br />
- simbolic: operează cu elemente ale textelor sursă ale programului ( linie<br />
sursă, variabilă, procedură, stivă de apel ale procedurilor). Acest tip de<br />
depanatoare se construiesc la implementarea limbajului de nivel înalt(ex. Pascal).<br />
Cel mai cunoscut exemplu de depanator simbolic este TURBO DEBUGGER ( Borland)<br />
pentru toate limbajele medii turbo (Pascal, C, Basic, Prolog, MSM).<br />
Bibliotecarul: program cu ajutorul căruia utilizatorul poate comanda păstrarea<br />
programelor proprii în fişierele de tip bibliotecă, poate copia, şterge insera, modifica<br />
programul în biblioteci. Exemple: LBR sub MS-DOS, "ar" sub UNIX, LIB80 sub CP/M<br />
Medii de programare: componente complexe destinate dezvoltării de programe.<br />
Înglobează următoarele componente:<br />
- editor texte;
- 23 -<br />
- compilator interactiv şi compilator serial( clasic);<br />
- editor de legături sau mecanism echivalent;<br />
- interpretor pentru execuţia rezultatului compilării;<br />
- depanator, de regulă simbolic;<br />
- o componentă de legătură cu exteriorul( cu SO).<br />
Suprafeţe de operare: au rolul de a "îmbrăca" SO pentru a face mai uşoară<br />
operarea (pentru IBM-PC şi componente; sub SO DOS şi UNIX). Înlocuiesc limbajul de<br />
control al SO.<br />
Exemple: XTREE, NC, PCSHELL, PROGRAM MANAGER, ...<br />
Din această prezentare se observă că SO au un caracter modular şi o structură<br />
ierarhică. Modularizarea constă în partiţionarea unui program mare în module cu sarcini<br />
precise, iar caracterul ierarhic în faptul că orice componentă acţionează sub controlul<br />
componentelor interioare ei, apelând primitivele oferite de acestea. Datorită acestor<br />
proprietăţi rezultă o implementare şi întreţinere mai uşoară si portabilitatea SO.<br />
1.2.3. Structurile unor SO particulare<br />
SO RSX<br />
Este un SO operaţional pe minicalculatoare compatibile PDP; echivalentul lui<br />
românesc este MIX, operaţional pe CORAL şi INDEPENDENT. Este un sistem<br />
interactiv cu multiprogramare care asigură controlul şi distribuţia resurselor SC între<br />
utilizatorii activi. Structura RSX este următoarea:<br />
F77 EDI PIP<br />
PAS EDT BRU<br />
XCC TKB DMP<br />
CBL LBR BAD<br />
BASIC ODT<br />
… … …<br />
Dezvoltare<br />
programe<br />
Tratare<br />
fişiere<br />
Programare<br />
Compilatoare<br />
Alte<br />
MCR<br />
.AT<br />
Monitor<br />
SGF<br />
Drivere<br />
Exploatare<br />
Monitorul: controlează activitatea sistemului, gestionează resursele sale şi<br />
execută directivele apelate de programele utilizator.
- 24 -<br />
Driverele: sunt programe (module) specializate care asigură interfaţa şi<br />
controlează operaţiile de I/O cu diferite tipuri de periferice ale sistemului.<br />
SGF: este un ansamblu de module pentru acces la fişiere şi controlul acestora;<br />
asigură crearea, prelucrarea, protecţia fişierelor.<br />
Procesorul de comenzi MCR (Monitor Consol Routine) este un task permanent<br />
activ ce lucrează sub controlul monitorului; preia de la terminale comenzile date de<br />
utilizator, le decodifică şi le trimite monitorului pentru executare.<br />
Procesorul fişierelor de comenzi indirecte “AT.” permite executarea fără<br />
intervenţia utilizatorului a unui şir de comenzi pregătite de utilizator într-un fişier.<br />
Conceptul de prompter. Un prompter este un grup de caractere care marchează<br />
momentele în care sistemul este pregătit să preia comenzi de la utilizator. RSX admite<br />
trei tipuri de prompter:<br />
- prompter implicit: > apare când lipsesc ceilalţi prompteri, terminalul nu este<br />
ocupat de sistem şi utilizatorul apasă ;<br />
- prompterul procesorului de comenzi: MCR > sau MCL > indică faptul că<br />
utilizatorul poate transmite sistemului comenzi ale MCR; apare şi la tastarea ;<br />
- prompteri de task: lll>; cele trei caractere reprezintă numele task-ului sub care se<br />
lucrează; se solicită comenzi proprii task-ului respectiv.<br />
UIC (User Identification Code): orice utilizator este recunoscut de către RSX<br />
prin intermediul unei perechi de numere octale [g,m] cu 0 g 377 şi 0 m 377; g<br />
este codul unui grup de utilizatori, iar m este numărul unui utilizator din grup.<br />
Funcţii ale UIC:<br />
- precizarea statutului utilizatorului faţă de resursele sistemului; g≤10<br />
înseamnă utilizator privilegiat (sau sistem), are la dispoziţie toate facilităţile oferite de<br />
către sistem; utilizatorii neprivilegiaţi nu pot modifica priorităţile unor utilizatori,<br />
definirea partiţiilor, nu au acces la fişiere speciale, nu au acces la unele periferice, ...<br />
- regăsirea fişierelor rezidente pe disc magnetic; fişierele unui utilizator<br />
sunt repertorizate într-un fişier numit UFD (User File Directory) legat de UIC<br />
(UFD=UIC director).<br />
Se mai utilizează noţiunile de<br />
UIC implicit (atribuit de RSX utilizatorului în sesiunea de lucru)<br />
UIC proprietar (de protecţie) cel sub care se deschide sesiunea de lucru; în<br />
general UIC-ul director coincide cu UIC-ul implicit şi cu cel de protecţie; UIC-ul de<br />
protecţie rămâne neschimbat, celelalte pot fi schimbate.<br />
UIC-uri speciale ce desemnează directoare speciale din RSX, de exemplu:[1,54]<br />
conţin task-urile SO;[5,54] conţin compilatoarele;[1,1] conţin bibliotecile sistem<br />
SO UNIX<br />
Este un SO interactiv, multiutilizator, de uz general, disponibil pe<br />
minicalculatoare, calculatoare medii-mari. UNIX a devenit SO universal, element de<br />
referinţă pentru toate SO desi este un sistem relativ mic.<br />
Structura SO UNIX este următoarea:
- 25 -<br />
- Manipulare fişiere generale: ls, cd, cat, mv, rm,…<br />
- Manipulare fişiere text: lp, split, sort, pr, paste,…<br />
- Editoare de texte: vi, ed, ex.<br />
- Preparare de documente: troff, nroff, tbl, equ, pic,…<br />
- Comunicaţii între utilizatori: write, who, mail, mesq,…<br />
- Dezvoltare de programe: C, cb, ar, Pascal, F77, shell,…<br />
- Administrare sistem: paswd, mkfs, cpio, tar,…<br />
Shell<br />
File System<br />
Kernel<br />
Cdevsw<br />
Bdevsw<br />
HARD<br />
Cdevsw şi Bdevsw sunt componente de legătură directă cu echipamentul hard şi<br />
nucleul sistemului. Sunt ansamble de rutine dependente de maşină prin care se realizează<br />
legătura cu perifericele sistemului de tip caracter respectiv bloc şi sistem; sunt scrise în<br />
limbaj de ansamblare( singurele componente scrise în acest limbaj) în aproximativ 1000<br />
linii sursă limbaj de asamblare.<br />
Kernel este nucleul SO, este scris în limbajul "C", are 10000-12000 linii sursă.<br />
Este independent de maşina pe care operează si este partea ascunsă utilizatorului, asupra<br />
căreia lucrează administratorul sistemului. Prin această componentă se realizează legături<br />
cu toate resursele sistemului (periferice, linii de comunicaţie, memorie, timp,...). Sarcinile<br />
principale ale nucleului sunt gestiunea proceselor şi gestiunea periferice. Nucleul conţine<br />
componenta de planificare.<br />
File System este componenta ce organizează şi gestionează datele ce se<br />
vehiculează în sistem si este cea mai importantă componentă a SO UNIX.<br />
Shell este interpretorul de comenzi UNIX. Sarcinile lui sunt:<br />
- supraveghează fiecare terminal, preia, decodifică şi transmite nucleului<br />
comenzile utilizator;<br />
- oferă utilizatorului posibilitatea să controleze succesiuni de comenzi adresate<br />
nucleului( shell este de fapt un limbaj de programare, instrucţiunile lui fiind comenzi<br />
UNIX);<br />
- ca legătură directă între utilizator şi nucleu Shell oferă posibilitatea redirectării<br />
I/O şi a legării pipe a programelor;<br />
Din punct de vedere al utilizatorului UNIX are 3 calităţi:<br />
- este un sistem interactiv: toate comenzile se primesc de la terminal în<br />
regim conversaţional;<br />
- este sistem multi-user: lucrează în acelaşi timp cu mai mulţi utilizatori;<br />
disciplina de servire este time-sharing;
- 26 -<br />
- este sistem multi-tasking: fiecare utilizator poate avea mai multe<br />
programe în<br />
execuţie: linia de terminal cu care se lansează o comandă după care va urma alta se<br />
termină cu &; nu pot fi lansate comenzi ce folosesc resurse în comun.<br />
Exemple:<br />
$ cp A B & - copiere fişiere<br />
$ lp C & - tipărirea fişierului C la imprimantă<br />
$ pascal D - compilarea Pascal a programului D.<br />
Manipularea de fişiere generale: afişarea rezumatelor unor directoare, copiere,<br />
concatenare, ştergere, schimbare poziţie fişiere în structura arborescentă.<br />
Manipularea fişierelor text: operaţii cu fişiere text: caută în fişiere anumite linii,<br />
detectează fişiere cu anumit conţinut, ordonează alfabetic liniile unui fişier text,<br />
determină numărul de linii, cuvinte în fişierul text,...<br />
Editoare de texte: UNIX a fost primul SO dotat cu editor de texte video, vi.<br />
Preparatoare de documente: utilitare ce permite punerea în pagină pentru<br />
manuale şi cărţi, permit utilizarea tabelelor, formulelor, ... ( într-o manieră mai greoaie ca<br />
WORD, VENTURA, dar s-au folosit acum 20 de ani).<br />
Comunicaţii între utilizatori: UNIX este SO cel mai răspândit ce practică poşta<br />
electronică în care conceptul fundamental este cel de căsuţă poştală, adică zonă în<br />
memoria internă sau pe disc proprie fiecărui utilizator unde se depun mesaje şi se preiau;<br />
expedierea şi prelucrarea se face periodic sau la cerere.<br />
Dezvoltare de programe: compilatoare pentru cele mai modene limbaje.<br />
Administratorul sistemului: are ca sarcini întreţinerea fişierelor de parole,<br />
evidenţa utilizatorilor, întreţinerea sistemului de fişiere de pe discuri şi benzi, efectuarea<br />
de salvări şi restaurări periodice.<br />
SO CP/M<br />
Este compus dintr-un nucleu rezident şi o serie de programe de sistem la care<br />
utilizatorul poate adăuga programe noi. Are ca şi caracteristici principale<br />
transportabilitatea programelor şi fişierelor şi modul simplu de operare. Structura( pentru<br />
microprocesoare pe 8 biţi) este următoarea:<br />
- Editoare de texte: ED, WS<br />
- Compilatoare: F80, CII, PASCAL, TURBO<br />
- Linkeditoare: L80, REL, LN, LINKMT<br />
- Bibliotecare: LIB80, LIBUTIL, LIBMT<br />
- Baze de date: DBASE2<br />
- Tratare fişiere: PIP, DIP, ERA, POWER, REN, TYPE<br />
CCP<br />
BDOS<br />
BIOS
- 27 -<br />
BIOS( Basic Input/Output System): preia şi uniformizează diferenţele<br />
constructive ale perifericelor ataşate fiecărui tip de microcalculator; conţine 17 rutine,<br />
punctele de intrare în ele apar la începutul BIOS într-o tabelă cu 17 instrucţiuni de salt.<br />
Această tabelă constituie interfaţa dintre BIOS şi BDOS (se poate utiliza şi ca interfaţă cu<br />
programele de aplicaţii).<br />
BDOS( Basic Disk Operating System): set de rutine, invariant în raport cu<br />
echipamentul, ce apelează funcţiile BIOS şi execută operaţiile I/O cu periferice standard.<br />
CCP (Console Command Processor): asigură interfaţa sistem operator; sunt<br />
rutine independente de echipament, se citesc şi se interpretează comenzile date de un<br />
terminal.<br />
Sub CP/M nu se pot dezvolta programe mai mari de 64 KO (practic 55 KO).<br />
SO MS-DOS<br />
Nucleele MS-DOS şi PC-DOS seamănă cu nucleul CP/M, dar sunt construite<br />
pentru microprocesoare pe 16 biţi. Structura sa este următoarea:<br />
Suprafeţe de operare XTPRO, NC, PCSHELL, WINDOWS<br />
- Compilatoare: F77, C, GWBASIC, …<br />
- Bibliotecar: LBR<br />
- Editoare de legături: LINK, TLINK<br />
- Preparatoare de documente: WS WORD, VENTURA,…<br />
- Editoare de texte: EDIT, WS, WORD,…<br />
- Medii de programare TURBO: PASCAL, C, PROLOG,…<br />
- Programe utilitare<br />
COMMAND<br />
BDOS<br />
DISK BIOS<br />
ROM BIOS<br />
ROM-BIOS: este o componentă livrată de firma producătoare a calculatoarelor în<br />
memoria ROM a SC şi egalizează toate diferenţele constructive ale SC faţă de convenţiile<br />
DOS. Oferă rutine de întrerupere prin care se realizează legătura cu perifericele.<br />
DISK-BIOS: componentă independent de hard ce extinde funcţia ROM-BIOS.<br />
Este conţinută în fişiere pe disc (IBMBIO.COM sau BIO.COM sau IO.SYS)<br />
Funcţiile BIOS:<br />
- încărcarea SO;<br />
- determinarea şi testarea componentelor periferice;<br />
- testarea memoriei RAM;
- 28 -<br />
- funcţia privind lucrul cu ecranul video;<br />
- funcţia pentru citirea tastaturii;<br />
- funcţia de lucru cu discuri (fixe şi flexibile);<br />
- funcţia pentru lucrul cu linii de comunicaţii asincronă (imprimante,<br />
plottere, ...)<br />
BDOS: extinde funcţia BIOS, mai ales cele referitoare la lucrul cu discuri. Este o<br />
componentă conţinută în fişiere pe disc (IBMDOS.COM sau DOS.COM sau<br />
MSDOS.SYS).<br />
Sarcini: - gestiunea memoriei (alocare, eliberare spaţii)<br />
- gestiunea proceselor (încărcare, lansare în execuţie, terminare);<br />
- execuţia operaţiilor de I/O cu periferice de tip caracter<br />
- tratare fişiere disc: creare, acces, deschidere, închidere, ştergere,<br />
redenumire, ...<br />
- protejarea fişierelor între mai multe procese active;<br />
- gestiunea structurilor arborescente şi manipularea directoarelor;<br />
- gestiunea reţelelor, orologiilor, calendarului.<br />
COMMAND: preia comenzile utilizatorului de la tastatură şi le lansează în<br />
execuţie. Este o componentă conţinută în fişierul command.com, numit interpretor de<br />
comenzi, pe discul de pe care se încarcă sistemul. Are multe facilităţi, dintre care<br />
redirectare, legare pipe, ...<br />
1.2.4. Cum devine operaţional un SO?<br />
Generare şi configurare<br />
De cele mai multe ori un SO este destinat numai unui tip de calculator, de<br />
exemplu SO SIRIS este propriu SC FELIX-C256, SO RSX propriu SC compatibile PDP.<br />
Au apărut în ultiml timp şi SO ce pot fi implementate pe mai multe tipuri de sisteme de<br />
calcul, sunt SO cu caracter portabil( efortul necesar trecerii de pe o maşină pe alta este<br />
foarte mic în comparaţie cu cel pentru rescrierea întregului SO).<br />
Exemplu - pentru CP/M trebuie rescrisă doar componenta BIOS;<br />
- pentru UNIX trebuie rescrise cele 1000 linii sursă în limbaj de asamblare<br />
şi maşina trebuie să aibă compilator "C".<br />
Orice SO trebuie adaptat la configuraţia hard a SC pe care va lucra. Pentru ca<br />
adaptarea să se facă uşor funcţiile SO trebuie să fie factorizate şi parametrizate. Este<br />
bine ca la proiectarea SO să fie avută în vedere posibilitatea de automatizare a procesului<br />
de adaptare.<br />
Procesul de adaptare a SO la configuraţii şi cerinţe date se numeşte generare,<br />
instalare sau configurare a SO. Prin generare se obţine imaginea unui disc sistem în care<br />
sunt memorate programele şi rutinele SO necesare şi suficiente realizării cerinţelor şi<br />
configuraţiei hard existente.<br />
Generarea constă în următoarele etape<br />
- alegerea unui disc sistem: 1) se verifică să nu aibă sectoare defecte,<br />
dacă este defect sectorul zero discul nu poate fi disc sistem<br />
2) se formatează discul;<br />
- un disc sistem trebuie sub orice SO să fie bootabil: după<br />
montarea discului, punerea sub tensiune a SC şi perifericelor, apăsarea butonului de
- 29 -<br />
BOOT şi eventual indicarea unităţii pe care este montat discul, SO se încarcă şi devine<br />
operaţional;<br />
- finalul generării presupune de obicei operaţii de copiere:<br />
administratorul de sistem completează discul cu programe pe care le consideră necesare;<br />
- generarea se face fără utilizatori în sistem.<br />
SO RSX<br />
Este configurat prin intermediul task-ului privilegiat VMR (Virtual Monitor<br />
Console Rontine) care poate lucra sau automat( cu fişier de comenzi) fie manual (<br />
comenzi de la inginerul de sistem). UIC-ul sub care se face generarea trebuie să fie<br />
privilegiat. In ultima fază a generării se crează fişiere de UIC-uri şi parole şi fişierul<br />
STARTUP.COM în care se trec comenzile RSX ce se execută la lansarea în execuţie a<br />
RSX.<br />
SO UNIX<br />
Detaliile generării SO UNIX sunt stabilite pentru fiecare tip de SC în parte de<br />
către echipa ce a implementat SO pe acel tip de maşină.<br />
Fiecare pachet UNIX de referinţă pentru un anumit tip de calculator dispune de<br />
fişiere de comenzi Shell pentru generare. Generarea UNIX înseamnă recompilarea tuturor<br />
componentelor ce vor intra în SO care se generează. Se livrează către beneficiar pe suport<br />
magnetic toate textele sursă "C" şi asamblare ce compun pachetul referinţă şi a<br />
documentaţiilor aferente. Folosind fişiere UNIX de tip MAKEFILE este posibilă<br />
compilarea produselor ce compun sistemul. Acest tip de fişiere este destinat compilării şi<br />
editării de legături ale unor produse program mari, obţinute din zeci, sute de fişiere sursă.<br />
Pregătirea generării înseamnă stabilirea valorilor concrete ale unor constante ce apar în<br />
aceste texte sursă (ex. # define, # sf.). Generarea este făcută de un specialist în<br />
implementarea UNIX pe maşina respectivă şi trebuie să asiste şi administratorul<br />
sistemului. În ultima fază a generării administratorul stabileşte parolele, conturile<br />
utilizatorului, drepturile lor etc.<br />
SO CP/M<br />
Generarea se face manual:<br />
- se formatează şi se verifică o dischetă( cu programele de formatare şi verificare<br />
existente).<br />
- se lansează în execuţie comanda SYSGEN (APPGEN) care citeşte nucleul<br />
CP/M de pe o dischetă sistem şi-l pune pe cea pregătită (nucleul conţine BIOS, BDOS,<br />
CCP şi programul BOOTSTRAP)<br />
- se copiază fişierele pe care utilizatorul doreşte să le aibă pe discheta respectivă;<br />
Observaţie: o dischetă poate conţine sistemele de operare pentru diferite tipuri de<br />
calculatoare.<br />
SO MS-DOS<br />
Generarea se face pe dischetă sau pe disc Winchester prin intermediul unor<br />
comenzi standard. La generarea unui disc DOS se şterg toate informaţiile vechi de pe<br />
discul respectiv.
- 30 -<br />
Etape:<br />
0) Partajarea discului Winchester( în 1-4 zone care se văd ca 1-4 discuri<br />
mai mici); se face cu comanda FDISK;<br />
1) Formatarea discului şi verificarea sectoarelor lui: cu comanda<br />
FORMAT cu opţiunea /S. Efecte:<br />
- în sectorul 0 se pune programul bootstrap de încărcare a SO pe disc<br />
- se depun pe disc fişierele IBMBIO.COM, IBMDOS.COM,<br />
COMMAND.COM<br />
- dacă s-a făcut partajarea trebuie formatate toate partiţiile (cu opţiunea /S<br />
se face pentru o singură partiţie care a fost declarată activă cu FDISK)<br />
2) Crearea fişierului de configurare: prin operaţia de configurare se fixează<br />
valorile unor parametri sistem:<br />
- numărul fişierelor deschise simultan;<br />
- numărul de zone tampon pentru I/O;<br />
- numărul şi dimensiunea stivelor;<br />
- condiţia de sesizare a tastării ;<br />
- convenţiile de ţară, timp, monedă;<br />
- precizarea unor drivere de I/O;<br />
- existenţa unui alt întrerupător de comenzi.<br />
Aceşti parametri sunt precizaţi în fişierul CONFIG.SYS (dacă lipseşte DOS le<br />
atribuie valori implicite ce depind de tipul de calculator).<br />
3) Crearea fişierului de comenzi iniţiale. După fixarea parametrilor de<br />
configuraţie şi încărcarea interpretorului de comenzi, DOS caută pe disc fişierul<br />
AUTOEXEC.BAT., fişier text ce conţine comenzile ce se vor executa la lansarea DOS.<br />
Comenzile se referă la:<br />
- fixarea datei şi orei exacte de pornire;<br />
- fixarea modului de afişare a prompterului;<br />
- fixarea directoarelor pe disc unde se caută comenzi externe ...<br />
4) Copierea fişierelor dorite a fi pe discul sistem(comanda XCOPY).<br />
Etapele 2-4( lansare, comanda FORMAT, creare fişiere CONFIG.SYS şi<br />
AUTOEXEC.BAT şi lansare XCOPY pentru fişiere ce conţin comenzi externe) se pot<br />
realiza automat cu comanda externă SELECT.<br />
Salvare, întreţinere, refacere<br />
Există agenţi care perturbă (distrug) informaţiile de pe disc. Aceşti agenţi pot fi:<br />
- accidentali (căderi de tensiune, distrugere fizică a discului, erori hard, ...)<br />
- rău intenţionaţi (intruşi ce caută acces la informaţii sau viruşi) - pentru<br />
contracarare se folosesc conturi, parole, drepturi de acces.<br />
În urma generării, utilizatorul trebuie să-şi pregătească copii ale discului generat;<br />
numărul de copii trebuie să fie direct proporţional cu efortul de generare şi importanţa<br />
sistemului.<br />
În timpul exploatării se crează fişiere ce pot fi importante. Utilizatorul trebuie să<br />
facă copii de siguranţă, iar administratorul sistemului trebuie să facă periodic copii pentru<br />
fişierele din întregul sistem.
- 31 -<br />
SO RSX<br />
Copierea de fişiere se face cu utilitarul PIP; pentru salvări masive se foloseşte<br />
utilitarul BRU (Backup and Restore Utility). BRU se poate folosi doar de către utilizatorii<br />
privilegiaţi şi oferă 2 servicii:<br />
- copierea fişierelor pe bandă, fişierele se depun pe bandă într-un format special<br />
pentru ca pe bandă să se poată face mai multe salvări succesive.<br />
-refacerea unor fişiere de pe disc prin copierea lor de pe banda pe care au fost<br />
salvate; restaurarea se poate face integral sau selectiv.<br />
SO UNIX<br />
cpio (Copy Input Output) - salvare şi restaurare SO şi salvare/refacere fişiere de<br />
pe disc pe bandă;<br />
tar (Tope Archive) - salvare/restaurare pe bandă a unui număr foarte mare de<br />
fişiere într-un format special astfel încât selecţia pentru restaurare să se poată face la nivel<br />
de fişier şi să se poată face salvări succesive;<br />
SO CP/M<br />
- permite salvarea de pe o dischetă pe alta<br />
- se folosesc utilizatoarele PIP, DIP şi POWER (pentru salvări masive)<br />
-<br />
SO MS-DOS<br />
- salvarea se face pe dischete;<br />
- cel mai comod se foloseşte comanda externă XCOPY;<br />
- se folosesc programe de comprimare (arhivare) pentru a minimiza dimensiunile<br />
fişierelor.<br />
Lansarea în execuţie<br />
Una din principalele sarcini ale SO este de a se autoîncărca pe disc şi a se<br />
autolansa în execuţie. Pentru lansare se foloseşte mecanismul Bootstrap (hard şi soft).<br />
Acesta constă (pe scurt) din următoarele: în momentul apăsării butonului de pornire,<br />
acest mecanism încarcă în memorie o anumită informaţie, de regulă un program ce<br />
execută o acţiune după care acesta se autoelimină din sistem; acest bootstrop este format<br />
de obicei dintr-un modul de program simplu care se poate încărca manual sau poate fi o<br />
funcţie cablată a SC lansabilă prin apăsarea unui buton. Informaţia încărcată în sistem de<br />
către bootstrap nu este monitorul rezident ci un program mai complex care ştie să încarce<br />
monitorul rezident şi să-l lanseze în execuţie (la SO mari între lansarea bootstrap şi<br />
lansarea monitorului apar mai multe programe care se execută şi apoi se autoelimină din<br />
memorie). În prezent, suportul magnetic de încărcare este sectorul zero al unui disc<br />
magnetic. La unele SO se indică de pe ce disc se încarcă programele SO (Loaderabsolut<br />
şi IncărcătorSO), la altele încărcarea se face în mod "stand-alone". La terminarea<br />
încărcării se lansează în execuţie un fişier de comenzi iniţiale, fişier care are un nume<br />
prestabilit; în absenţa acestui fişier sistemul atribuie valori iniţiale prestabilite pentru<br />
parametrii sistemului.<br />
Etapele încărcării şi lansării în execuţie a SO<br />
1) Se apasă şi în acest moment programul APASASTART citeşte în<br />
primele n locaţii de memorie( notate M[0], M[1], …) codul maşină al programului<br />
LOADERABSOLUT; n reprezintă lungimea unui sector de pe discul de încărcare.
- 32 -<br />
APASASTART:<br />
for i:=1 to n do read (M[i]);<br />
transferla (M[0]);<br />
{se citesc primele n rânduri de la intrarea standard, se depun în primele n locaţii<br />
de memorie şi se trece la executarea instrucţiunii al cărei cod se află în prima locaţie}<br />
2) După transferla (M[0]) intră în lucru programul LOADERABSOLUT<br />
LOADERABSOLUT:<br />
repeat<br />
for i:=1 to n do read(M[r+i]);<br />
A:= M[r]; k:=M[r+i];<br />
if k=0 then go to LANSARE<br />
for i:=0 to k-1 do M[A+i]:=M[r+2+i]<br />
until false;<br />
LANSARE:<br />
transferla (A);<br />
r: adresa de la care există n locaţii libere în memorie<br />
3) Programul LOADERABSOLUT citeşte un program care poate fi oricât de<br />
sofisticat, ÎNCARCATORSO<br />
4) După executarea ultimei instrucţiuni transferla(A) din LODERABSOLUT întră<br />
în lucru ÎNCARCATORSO care încarcă de pe disc programele şi rutinele (nucleul) SO.<br />
5) La terminarea încărcării ÎNCARCATORSO execută:<br />
- ştergerea din memorie a programului APASASTART<br />
- ştergerea din memorie a programului LOADERABSOLUT<br />
- eliberarea spaţiului de memorie ocupat de el cu excepţia unei porţiuni<br />
- executarea instrucţiunii transferla (ASSO), unde ASSO este adresa de<br />
start a SO<br />
- după acestea, încărcătorul îşi închide activitatea<br />
Codul programului APASASTART se plasează cu ajutorul unor instrucţiuni<br />
maşină cablate sau existente în ROM de unde se lansează prin hard.<br />
Încărcarea unor SO particulare<br />
RSX.<br />
La apăsarea cheii BOOT se citeşte în memorie primul bloc din fişierul<br />
[0,0]INDEXF.SYS;1 care coincide cu primul bloc fizic al discului şi care conţine<br />
programul bootstrop al SO. Pe ecran apare prompter-ul şi se citeşte numele RSX al<br />
discului de pe care are loc încărcarea. După încărcare, se caută pe disc fişierul de<br />
comenzi iniţiale [1,2]STARTUP.COM<br />
UNIX. Are loc un dialog între administrator şi sistem: boot device? div (0,0) unix<br />
dw: specifică perifericul discului de pe care se face încărcarea sistemului<br />
0: numărul de ordine al discului din familia dw<br />
0: numărul blocului (sectorului) pe disc unde se află directorul rădăcină<br />
(root) al<br />
discului<br />
- la pornire, după terminarea încărcării UNIX caută fişierul de comenzi iniţiale<br />
/etc/rc<br />
CP/M. Încărcarea se face întotdeauna de pe prima unitate de dischetă (în unitatea<br />
"A:" trebuie să fie dischetă sistem). Pe primul sector se află programul bootstrap, pe
- 33 -<br />
următoarele sectoare ale pistelor 0 şi 1 se află nucleul CP/M (componentele BIOS,<br />
BDOS, CCP); acestea se încarcă în memorie RAM şi se lansează în execuţie CCP.<br />
Dacă în "A:" se află dischetă sistem atunci intră în lucru monitorul sistemului ale<br />
cărui rutine se află în memorie ROM; se afişează prompter-ul şi se aşteaptă comenzi;<br />
pentru a se intra în CP/M se introduce în "A:" o dischetă sistem şi se dă comanda<br />
>GF800 (la adresa F800 în ROM se află rutina de început a încărcării).<br />
MS-DOS. Încărcarea se face la punerea sub tensiune a SC. Procesul începe cu<br />
lansarea unei rutine din ROM-BIOS care tratează componentele hard ale SC; urmează<br />
încărcarea de pe prima unitate de disc sau de pe hard; se încarcă întâi fişierele<br />
IBMBIO.COM şi IBMDOS.COM; urmează configurarea sistemului: se caută în<br />
directorul rădăcină al discului de încărcare fişierul CONFIG.SYS (fişier text). În ultima<br />
etapă se lansează în execuţie fişierul COMMAND.COM, acesta caută în directorul<br />
rădăcină fişierul AUTOEXEC.BAT şi execută comenzile din el.<br />
Comenzi de configurare:<br />
BREAk = ON sau BREAK = OFF - se stabilesc condiţiile în care sistemul<br />
cercetează tastarea CTRL/C sau CTRL/Break, la fiecare apel sistem respectiv doar la<br />
operaţii I/O cu consolă, imprimantă sau adaptoare asincrone de comunicaţii.<br />
BUFFER = n - n{ 1, 2, …, 99} reprezintă numărul zonelor tampon alocate de<br />
sistem pentru schimburile cu discul;<br />
FILES = m - m{ 8, 9, …, 255} numărul maxim de fişiere ce pot fi deschise<br />
simultan pentru toate programele active din sistem; pentru un program m 20 (fişiere<br />
nedefinite: I, O, erori, auxiliar pentru imprimantă, ...)<br />
DEVICE = [d:][cale] fişier - se specifică numele unui fişier ce conţine drivere<br />
I/O altul decât cel standard;<br />
drivere accesibile: ANSI.SYS (extinderea funcţiei de control ale ecranului şi<br />
tastaturii)<br />
DRIVER.SYS (crearea unor echipamente logice de tip disc<br />
asociate unor echipamente fizice)<br />
RAMDRIVER.SYS ( oferă posibilitatea folosirii unui disc<br />
ce are<br />
ca suport fizic o porţiune din RAM, viteza de acces este mai mare)<br />
SMARTDRV.SYS ( se creează mecanismul de memorie<br />
cache; este posibil doar pentru microprocesoare cel puţin 386 şi sistemul de operare DOS<br />
cel puţin versiunea 5.0)
- 34 -<br />
<strong>CAPITOLUL</strong> II<br />
COMPONENTE ŞI CONCEPTE FUNDAMENTALE<br />
2.1. Procese<br />
2.1.1. Conceptul de proces<br />
La proiectarea unui sistem complex este necesară descompunerea lui în<br />
subsisteme, adică modularizarea. Pentru proiectarea unui SO trebuie ţinut cont de faptul<br />
că în funcţionare apare un grad de nedeterminism: funcţii sau servicii ale SO pot fi<br />
solicitate de către evenimente ce apar la momentul de timp şi cu frecvenţe imprevizibile:<br />
- cereri de schimb între memoria internă şi suportul extern de memorie;<br />
- cereri de ocupare pentru perioade nedeterminate a unor periferice fizice, blocuri<br />
de memorie sau componente soft;<br />
- solicitarea sistemului de către utilizatori;<br />
- apariţia unor erori soft sau hard.<br />
Pentru a putea satisface aceste cereri se introduce conceptul de proces sau task:<br />
calcul ce poate fi executat concurent (în paralel) cu alte calcule. Este o abstractizare a<br />
activităţii procesorului, fiind considerat ca un program în execuţie.<br />
Existenţa unui proces depinde de existenţa a trei factori:<br />
a) o procedură (set de instrucţiuni) ce trebuie executată;<br />
b) un procesor ce poate executa instrucţiunile;<br />
c) un mediu (memorie, periferice) asupra căruia să acţioneze procesorul.<br />
Paralelismul proceselor trebuie înţeles astfel: dacă P i şi P j sunt două procese, iar<br />
I i , I j respectiv H i , H j sunt momentele de început respectiv sfârşit ale lor, atunci P i şi P j se<br />
execută concurent dacă min (I i ,I j ) min (H i ,H j )<br />
(de exemplu P i începe şi se termină<br />
numai după ce a început P j ).<br />
Dacă există 2 procesoare este posibil un paralelism efectiv, P i şi P j pot fi simultan<br />
în starea RUN; în caz contrar procesorul execută alternativ instrucţiuni din cele 2 procese,<br />
SO le comută între stările RUN şi READY.<br />
Definiţia 2.1.1. Două instrucţiuni succesive S1 şi S2 pot fi executate în paralel<br />
dacă efectul lor asupra mediului este acelaşi, indiferent dacă se execută întâi complet S1<br />
şi apoi S2, invers sau execuţia uneia începe înainte de a se termina execuţia celeilalte.<br />
Exemplu 2.1.1: S1: read (a);<br />
S2: read (b); S1 şi S2 sunt executabile în paralel<br />
S3: c:= a+b;<br />
S4: write (c);<br />
Definiţia 2.1.2. Un graf aciclic (X,U) este graf de precedenţă asociat unui<br />
program dacă X este mulţimea instrucţiunilor programului, iar U={ ( S i , S j )| S j urmează<br />
imediat după S i şi se poate executa numai după terminarea lui S j } este mulţimea arcelor.
- 35 -<br />
Pentru exemplul 2.1.1 prezentat graful de precedenţă este următorul:<br />
S1<br />
S2<br />
S3<br />
Figura 2.1.1<br />
S4<br />
Un alt exemplu de graf de precedenţă:<br />
S1<br />
S2<br />
S3<br />
Figura 2.1.2<br />
S4<br />
S5<br />
S6<br />
S7<br />
Condiţii de paralelism. Când două instrucţiuni se pot executa în paralel?<br />
Fie R(S i )= { a 1 ,…, a m } mulţimea variabilelor referite de S i şi ale căror valori<br />
nu sunt modificate de către instrucţiunea S I şi<br />
W(S i )= { b 1 ,…, b n } mulţimea variabilelor referite de S i şi ale căror valori<br />
sunt modificate de S i .<br />
În exemplul 2.1.1 R(S1)= , W(S1)= { a}<br />
R(S2)= , W(S2)= { b}<br />
R(S3)= { a, b}, W(S3)= { c}<br />
R(S4)= { c}, W(S4)= .<br />
Teorema 2.1.1 (Bernstein). Două instrucţiuni vecine S 1 şi S 2 pot fi executate în<br />
paralel dacă şi numai dacă<br />
1) R(S 1 ) W(S 2 )= <br />
2) R(S 2 ) W(S 1 )= <br />
3) W(S 1 ) W(S 2 )=
- 36 -<br />
2.1.2. Mecanisme de specificare a concurenţei<br />
Grafurile de precedenţă sunt un model matematic comod, dar nu pot fi folosite în<br />
mod direct pentru specificarea concurenţei în limbaje de programare. Pentru aceasta se<br />
vor folosi următoarele construcţii:<br />
a) Mecanismul FORK-JOIN-QUIT<br />
A fost introdus de către Conway(1963) şi îmbunătăţit de către Denning şi Von<br />
Horn (1966)<br />
Sintaxa:<br />
FORK etichetă;<br />
Se creează două procese care se vor executa concurent. Instrucţiunile primei<br />
secvenţe încep la etichetă, iar instrucţiunile celei de-a doua la instrucţiunea ce urmează<br />
după FORK;<br />
JOIN număr, etichetă;<br />
Se aşteaptă terminarea a numărului de procese care o execută; dacă a fost<br />
executată de mai puţin de număr ori atunci se trece la instrucţiunea ce urmează, după ce<br />
s-a executat a număr oară se trece la instrucţiunea cu etichetă. Este o secvenţă<br />
indivizibilă şi are efectul:<br />
număr:= număr –1;<br />
If număr=0 then goto etichetă;<br />
QUIT; - are ca efect terminarea procesului care o execută; urmează după JOIN<br />
Pentru cele două grafuri de precedenţă prezentate, scrierea cu ajutorul<br />
mecanismului FORK-JOIN-QUIT este următoarea<br />
m:=2; S1;<br />
FORK L1<br />
m:=3;<br />
read (a); FORK L1;<br />
goto L2; S2;<br />
L1: read (b); S4;<br />
L2: JOIN m, L3; FORK L2;<br />
QUIT S5;<br />
L3: c:=a+b; goto L3;<br />
write (c); L2: S6;<br />
goto L3;<br />
L1: S3;<br />
L3: JOIN m, L4;<br />
QUIT;<br />
L4: S7.<br />
b) Mecanismul PARBEGIN-PAREND<br />
Mecanismul a fost introdus de Dijkstra în 1965 (PARalel BEGIN-PARalel END)<br />
Sintaxa: S 0 ; PARBEGIN S 1 | S 2 | ... | S n PAREND; S n+1 ;<br />
şi corespunde grafului de precedenţă:
- 37 -<br />
S 0<br />
S 1 S 2<br />
. . .<br />
S n<br />
S n+1<br />
Figura 2.1.3<br />
şi are semnificaţia: instrucţiunile secvenţiale S 1 , ...,S n sunt lansate în execuţie simultan şi<br />
sunt executate concurent; terminarea grupului are loc după terminarea instrucţiunii ce<br />
durează cel mai mult.<br />
Pentru grafurile de precedenţă prezentate, scrierea cu mecanismul PARBEGIN-<br />
PAREND este următoarea:<br />
PARBEGIN S 1 ;<br />
read (a);<br />
PARBEGIN<br />
read (b);<br />
begin<br />
PAREND; S 2 ; S 4 ;<br />
c:=a+b;<br />
PARBEGIN<br />
write (c); S 5 ;<br />
S 6 ;<br />
PAREND<br />
end<br />
S 3 ;<br />
PAREND;<br />
S 7 .<br />
- avantajele mecanismului: completarea limbajelor de programare cu structură de<br />
bloc (Pascal, "C", Ada) cu aceste construcţii este o extensie naturală; programul îşi<br />
păstrează claritatea<br />
- dezavantajele mecanismului: există grafuri ce pot fi descrise cu FORK-JOIN-<br />
QUIT, dar nu cu PARBEGIN-PAREND, ca exemplu:<br />
S1<br />
S2<br />
S3<br />
S4<br />
Figura 2.1.4<br />
S5<br />
S6<br />
S7
- 38 -<br />
c) Conceptul de semafor<br />
A fost introdus de Dijkstra pentru a evita cazurile în care grafuri de precedenţă nu<br />
pot fi descrise cu mecanismul PARBEGIN- PAREND.<br />
Semaforul s este perechea (v(s), c(s)) unde v(s) este valoarea semaforului, iar c(s)<br />
o coadă de aşteptare.<br />
v(s) este un întreg ce primeşte o valoare iniţială v 0 ( s);<br />
c(s) conţine (pointeri la) procesele ce aşteaptă la semaforul s.<br />
Operaţii pentru gestiunea semafoarelor<br />
P(s) – are semnificaţia:"a trece de" sau WAIT şi este o operaţie indivizibilă.<br />
P(s) apelat de procesul A înseamnă<br />
v(s):=v(s)-1;<br />
if v(s)
- 39 -<br />
Fie<br />
np(s)= primitive P(s) efectuate până la un moment dat;<br />
nv(s)= primitive V(s) efectuate până la un moment dat;<br />
v 0 (s)= valoarea iniţială a semaforului<br />
nt(s)= numărul de procese ce au trecut de semaforul s<br />
Teorema 2.2. Au loc proprietătile:<br />
1) v(s)=v 0 (s)-nv(s);<br />
2) dacă v(s)< 0 atunci în c(s) există -v(s) procese;<br />
3) dacă v(s) 0 atunci v(s) procese pot trece succesiv semaforul s fără a fi blocate;<br />
4) nt(s)= min {v 0(s)+nv(s),np(s)}<br />
Demonstraţia se face prin inducţie după numărul operaţiilor P şi V efectuate<br />
asupra semaforului.<br />
Aspect critic: două procese nu pot executa în acelaşi timp aceeaşi operaţie P sau<br />
V asupra aceluiaşi semafor s.<br />
Combinând semafoarele cu mecanismul PARBEGIN-PAREND se obţin<br />
construcţii la fel de puternice ca FORK-JOIN-QUIT. De exemplu, pentru figura 2.1.4:<br />
Fie MS= { a, b, c, d, e, f, g} o mulţime de semafoare cu valoarea iniţială<br />
v 0(s) s<br />
MS . Secvenţa de instrucţiuni din fig.4 se poate descrie astfel:<br />
PARBEGIN<br />
begin S1; V(a); V(b) end;<br />
begin P(a); S2; S4; V(c); V(d) end;<br />
begin P(b); S3; V(e) end;<br />
begin P(c); S5; V(f) end;<br />
begin P(d); P(e); S6; V(g) end;<br />
begin P(f); P(g); S7 end<br />
PAREND;<br />
2.1.3. Elemente de programare paralelă şi concurentă<br />
La începutul capitolului s-a făcut precizarea că până la un punct termenii de<br />
programare paralelă şi programare concurentă se vor considera sinonimi. Iată însă prin ce<br />
se deosebesc aceste două tipuri de programare:<br />
Caracteristic programării paralele este faptul că procesele ce se desfăşoară în<br />
paralel nu colaborează între ele, nu colaborează şi execuţia unuia nu este în nici un<br />
moment independentă de rezultatele parţiale ale execuţiei celuilalt. Referitor la<br />
programarea paralelă apar câteva probleme: înţelegerea unui program ce descrie activităţi<br />
ce se desfăşoară în paralel( încercaţi sa citiţi în acelaşi timp două cărţi, câte un rând din<br />
fiecare!); depanarea unui program paralel este foarte dificilă, este de multe ori imposibil<br />
de detectat secvenţa ce a produs o eroare; este dificilă demonstrarea corectitudinii<br />
programelor; este o problemă găsirea activităţilor care pot să se desfăşoare în paralel.<br />
Avem de a face cu programare concurentă atunci când procesele paralele se<br />
intercondiţionează reciproc. În ceea ce urmează se vor da câteva exemple de<br />
intercondiţionare a proceselor şi de probleme ridicate de programarea concurentă.<br />
Secţiune critică; resursă critică; excludere mutuală
- 40 -<br />
Să presupunem că două procese P 1 şi P 2 au dreptul să modifice valoarea unei<br />
variabile v sub forma: P 1 : v:= v+1 şi P 2 : v:= v+1; cele două procese execută această<br />
incrementare concurent şi de un număr neprecizat de ori( ex.: două agenţii CFR care dau<br />
locuri simultan la acelaşi tren, v poate fi numărul curent al locului vândut). Reprezentarea<br />
lor poate fi următoarea:<br />
PARBEGIN<br />
P 1 : ... v:= v+1;...¦<br />
P 2 : ... v:= v+1;...<br />
PAREND;<br />
Pentru reprezentarea instrucţiunii v:= v+1 sunt necesare trei instrucţiuni maşină( care nu<br />
pot fi întrerupte): r:= v; r:= r+1; v:= r; unde r este un registru al maşinii. Dacă cele două<br />
procese folosesc două registre r 1 şi r 2 , se pot da două secvenţe ce pot fi executate de către<br />
cele două procese:<br />
P 1 : r 1 := x; P 2 : . . .<br />
r 1 := r 1 +1; . . .<br />
x:= r 1 ; . . .<br />
. . . r 2 :=x;<br />
. . . r 2 := r 2 +1;<br />
. . . x:= r 2 ;<br />
secvenţa 1( dublă incrementare)<br />
P 1 : r 1 := x; P 2 : . . .<br />
r 1 := r 1 +1;<br />
r 2 :=x;<br />
x:= r 1 ; r 2 := r 2 +1;<br />
. . . x:= r 2 ;<br />
secvenţa 2( dublă incrementare)<br />
Dacă la începutul fiecărei secvenţe variabila v are valoarea 5, atunci în urma<br />
executării secvenţei 1 variabila v va avea valoarea 7( primeşte valoarea 6 de la P 1 şi apoi<br />
7 de la P 2 ), iar în urma executării secvenţei 2 v va avea valoarea 6!<br />
Porţiunea de program v:= v+1 este secţiune critică, deoarece ea nu poate fi<br />
executată simultan de către două procese. Variabila v se numeşte resursă critică, ea nu<br />
poate fi accesată simultan de către două procese. Despre procesele P 1 şi P 2 se spune că se<br />
exclud reciproc, deoarece au acces exclusiv la secţiunea şi la resursa critică.<br />
Problema secţiunii critice a suscitat un interes deosebit în istoria SO. Iată care<br />
sunt cerinţele acestei probleme:<br />
- la un moment dat un singur proces se poate afla în secţiunea critică; orice alt<br />
proces care solicită acces la secţiunea critică îl va primi numai după ce procesul care o<br />
execută a terminat instrucţiunile secţiunii critice;<br />
- vitezele relative ale proceselor sunt necunoscute;<br />
- oprirea oricărui proces are loc numai în afara secţiunii critice;<br />
- nici un proces nu va aştepta la infinit accesul în secţiunea critică.
- 41 -<br />
Au existat multe încercări de rezolvare a problemei secţiunii critice. S-au încercat<br />
soluţii care să folosească numai elemente secvenţiale şi construcţii PARBEGIN-<br />
PAREND. Nici una dintre aceste soluţii nu respectă însă toate condiţiile enumerate<br />
anterior. În 1965 matematicianul Dekker a dat o soluţie rezonabilă, dar foarte încâlcită. În<br />
1981 Peterson a dat o soluţie ceva mai simplă:<br />
var c1, c2: boolean;<br />
schimb: integer;<br />
c1:= true; c2:= true;<br />
PARBEGIN<br />
P1: repeat<br />
c1:= false; schimb:=1;<br />
while (( not c2) and (schimb=1)) do ; { aşteaptă}<br />
secţiune critică;<br />
c1:= true;<br />
rest program1<br />
until false<br />
¦<br />
P2: repeat<br />
c2:= false; schimb:=2;<br />
while (( not c1) and (schimb=2)) do ; { aşteaptă}<br />
secţiune critică;<br />
c2:= true;<br />
rest program2<br />
until false<br />
PAREND<br />
Soluţia dată însă nu rezolvă cazul în care secţiunea critică trebuie accesată de mai<br />
mult de două procese, iar generalizarea nu este uşoară. În plus, se practică o aşteptare<br />
activă: în faza de aşteptare toate procesoarele execută o aceeaşi instrucţiune; ar fi de dorit<br />
ca pe timpul aşteptării procesorul sa devină disponibil pentru alte procese.<br />
O rezolvare elegantă este folosirea semafoarelor. Iată descrierea acestei soluţii<br />
care foloseşte un singur semafor, s:<br />
var s: semaphore;<br />
v0(s ):=1;<br />
PARBEGIN<br />
P1: repeat<br />
P(s);<br />
secţiune critică;<br />
V(s);<br />
rest program1<br />
until false<br />
¦<br />
P2: repeat<br />
P(s);
- 42 -<br />
PAREND<br />
secţiune critică;<br />
V(s);<br />
rest program2<br />
until false<br />
Soluţia prezentată este corectă indiferent de numărul de procese care cer acces în<br />
secţiunea critică. Dacă v 0 (s)=1 şi toate procesele ce folosesc secţiunea critică sunt de<br />
forma: P i : . . . P(s); secţiune critică; V(s); . . . atunci se poate demonstra că v(s) 1<br />
oricare ar fi numărul proceselor care operează asupra lui s cu operaţii P sau V. În baza<br />
teoremei 2.2 rezultă că un singur proces poate trece de semaforul s, deci sunt îndeplinite<br />
condiţiile ce definesc o secţiune critică. Un semafor de acest tip se numeşte semafor de<br />
excludere mutuală.<br />
Sincronizarea proceselor<br />
Enunţul operaţiei de sincronizare a proceselor este următorul: un proces P 1 nu<br />
poate trece de un anumit punct A decât după ce un alt proces P 2 ajunge într-un punct B<br />
(se stabileşte o relaţie de precedenţă între procese). Folosind semafoarele operaţia se<br />
descrie astfel:<br />
var s: semaphore;<br />
v 0 (s):=0;<br />
PARBEGIN<br />
P1: repeat . . . A; P(s); . . . until false<br />
¦<br />
P2: repeat . . . B; V(s); . . . until false<br />
PAREND<br />
Procesul P 1 va aştepta în punctul A prin operaţia P(s) până când procesul B va<br />
executa în punctul B operaţia V(s).<br />
Sincronizarea proceselor este o operaţie fundamentală în programarea concurentă.<br />
În secţiunile ce urmează se vor prezenta mai multe aplicaţii ale ei.<br />
Problema producătorului şi a consumatorului<br />
Există sisteme în care procesele sunt împărţite în două clase dependente una de<br />
cealaltă prin intermediul unei variabile numite buffer cu n intrări pentru n articole: există<br />
unul sau mai multe procese numite producătoare care depun produse în buffer de fiecare<br />
dată când sunt apelate şi unul sau mai multe procese numite consumatoare care consumă<br />
un produs din buffer de fiecare dată când sunt apelate( de exemplu conceptele de pipe şi<br />
spool-ing sunt de această natură). Fiecare producător depune un articol în buffer, iar<br />
fiecare consumator scoate câte un articol din buffer. Problema constă în a dirija cele două<br />
tipuri de procese astfel încât:<br />
a) să existe acces exclusiv la buffer;<br />
b) consumatorii să aştepte când buffer-ul este gol;
- 43 -<br />
c) producătorii să aştepte când buffer-ul este plin.<br />
Rezolvarea acestei probleme se poate face utilizând trei semafoare: gol care<br />
contorizează locurile libere din buffer, plin care contorizează produsele ce ocupă bufferul<br />
şi exclus care este un semafor de excludere mutuală, după cum urmează:<br />
var plin, gol, exclus: semaphores;<br />
v0( plin):=0;<br />
v0(gol):=n;<br />
v0(exclus):=1;<br />
PARBEGIN<br />
Producător: repeat<br />
produce articol;<br />
P(gol);<br />
P(exclus);<br />
depune articol în buffer;<br />
V(exclus);<br />
V(plin);<br />
until false<br />
¦<br />
Consumator: repeat<br />
P(plin);<br />
P(exclus);<br />
extrage articol din buffer;<br />
V(exclus);<br />
V(gol);<br />
consumă articol<br />
until false<br />
PAREND<br />
Regiuni critice condiţionate<br />
Prin intermediul operaţiilor de excludere şi sincronizare pot fi rezolvate o serie de<br />
probleme de concurenţă. Însă manipularea operaţiilor P şi V cere o foarte mare<br />
îndemănare. Din acest motiv au fost introduse construţii structurate de concurenţă prin<br />
intermediul cărora se poate exercita un control riguros al încălcării regulilor de<br />
concurenţă. O astfel de construcţie este regiunea critică condiţionată care înglobează<br />
noţiunile de regiune gritică şi resursă critică şi posibilitatea de a executa regiunea numai<br />
dacă este îndeplinită o anumită condiţie. Fiecărei regiuni critice i se asociază o resursă ce<br />
constă din toate variabilele ce trebuie protejate în regiune. Declararea ei se face astfel:<br />
resource r :: v 1 , v 2 , ..., v n<br />
unde r este numele resursei, iar v 1 , v 2 , ..., v n sunt numele variabilelor de protejat.<br />
O regiune critică condiţionată se defineşte astfel:<br />
region r [ when B ] do S
- 44 -<br />
unde r este numele unei resurse declarate ca înainte, B este o expresie booleană, iar S este<br />
secvenţa de instrucţiuni corespunzătoare regiunii critice. Dacă este prezentă opţiunea<br />
when, atunci S este executată numai dacă expresia B are valoarea adevărat. Variabilele<br />
din resursa r pot fi folosite numai de către instrucţiunile din secvenţa S. Descrierea prin<br />
semafoare a unei regiuni critice condiţionate se face folosind două semafoare: şir care<br />
reţine în coada lui toate procesele care cer acces la regiunea critică şi exclus care asigură<br />
acces exclusiv la anumite secţiuni şi un întreg nr ce reţine câte procese au cerut acces la<br />
regiune la un moment dat.<br />
Valorile de pornire sunt:<br />
var şir, exclus: semaphore;<br />
nr: integer;<br />
v0(şir):=0;<br />
v0(exclus):=1;<br />
nr:=0;<br />
Codul corespunzător regiunii:<br />
P(exclus);<br />
nr:=nr+1;<br />
while not B do<br />
begin<br />
V(exclus);<br />
P(şir);<br />
P(exclus)<br />
end;<br />
nr:=nr-1;<br />
S;<br />
for i:=1 to nr do V(şir);<br />
V(exclus);<br />
O aplicaţie a regiunilor critice condiţionate este:<br />
Problema citirilor şi scrierilor<br />
Problema a fost formulată de către Courtois, Heymans şi Parnas în 1971. Se<br />
presupune că există două tipuri de procese: cititor şi scriitor care partajează o resursă, de<br />
exemplu un fişier. Un proces scriitor modifică conţinutul fişierului, iar un proces cititor<br />
consultă informaţiile din el. Orice proces scriitor are acces exclusiv la resursă, dar<br />
procesele cititor pot avea mai multe acces simultan la ea( spre deosebire de problema<br />
producătorului şi consumatorului unde toate procesele aveau acces exclusiv la resursă).<br />
Între cerinţele problemei trebuie să se aibă în vedere ca nici un proces să nu aibă de<br />
aşteptat o perioadă nedefinită de timp şi în cazul accesului simultan să se precizeze care<br />
sunt procesele prioritare<br />
O rezolvare ce foloseşte regiunile critice este cea dată de P.B.Hansen în 1973.<br />
Această soluţie dă prioritate proceselor scriitor faţă de cele cititor. Un proces scriitor intră<br />
în lucru imediat ce procesele cititor active şi-au încheiat citirile curente. Resursa f este un<br />
fişier la care doresc accesul cele două tipuri de procese. Operaţiile de bază asupra
- 45 -<br />
fişierului sunt read şi write. Resursa c conţine două contoare nr şi nw care indică numărul<br />
de procese de citire respectiv de scriere au cerut acces la fişierul f.<br />
resource f:: ... ;<br />
resource c:: nr, nw: integer;<br />
nr:=0;<br />
nw:=0;<br />
procedure cititor;<br />
begin<br />
region c when nw=0 do nr:=nr+1;<br />
read ...;<br />
region c do nr:=nr-1<br />
end;
- 46 -<br />
procedure scriitor;<br />
begin<br />
region c do nw:=nw-1;<br />
region c when nr=0 do ; { aşteaptă terminarea cititorilor activi}<br />
region f do write ... ;<br />
region c do nw:=nw+1<br />
end;<br />
Limbaje de programare concurentă<br />
Există multe limbaje de programare care au încorporate mecanisme de<br />
comunicare şi sincronizare între procese. Iată câteva dintre acestea:<br />
PASCAL CONCURENT( P.B. Hansen 1975) dispune de trei tipuri de module:<br />
procese( entităţi de calcul secvenţiale care nu-şi partajează nici o variabilă), clase( tipuri<br />
de date abstracte utilizabile individual de către procese sau monitoare) şi monitoare(<br />
module apelabile de către procese în mod exclusiv, conţin toate datele ce trebuie să fie<br />
partajate între procese).<br />
ADA( 1980) are ca şi concept central modulul task, ce poate fi executat în paralel<br />
cu alte task-uri. Task-urile pot comunica între ele folosind conceptul de rendez-vous: fie<br />
A şi B două task-uri ce lucrează simultan. La un moment dat execuţia lui A depinde de<br />
informaţii furnizate de către B. Sunt posibile trei situaţii:<br />
a) task-ul B este gata să transmită informaţiile, dar task-ul A nu le-a cerut încă;<br />
b) task-ul B este gata să transmită informaţiile, iar task-ul A cere aceste date. În<br />
acest caz se realizează un rendez-vous, cele două procese lucrează sincron până se<br />
termină schimbul de informaţii după care fiecare îşi continuă activitatea independent;<br />
c) task-ul A lansează cererea, dar B nu este pregătit să furnizeze informaţiile. În<br />
cazurile a) şi c) task-ul B respectiv A aşteaptă întâlnirea cu celălat task.<br />
MODULA2 este un descendent din Pascal şi are facilităţi puternice pentru<br />
specificarea paralelismului şi concurenţei. Se găseşte deja implementat pe diferite tipuri<br />
de calculatoare, inclusiv IBM_PC.<br />
CHILL este proiectat în special pentru telecomunicaţii.<br />
“C” nu este un limbaj concurent, dar dispune de funcţii ce-i permit implementarea<br />
concurenţei( ex. concurenţa “C” sub UNIX).<br />
2.1.4. Problema impasului<br />
Conceptul de impas. Fie succesiunea proceselor A şi B din următoarea secvenţă:<br />
var x, y: semaphores;<br />
v0(x):=1; v0(y):= 1;<br />
PARBEGIN<br />
A: . . . P(x); . . . P(y); . . .<br />
¦<br />
B: . . . P(y); . . . P(x); . . .<br />
PAREND
- 47 -<br />
Dacă procesul A trece de P(x), dar înainte ca el să treacă de P(y) procesul B trece<br />
de P(y), atunci cele două procese se aşteaptă reciproc şi nu mai avansează nici unul.<br />
Acest lucru se întâmplă din cauză că procesele îşi ocupă resursele doar atunci când au<br />
nevoie de ele şi pot să apară situaţii de aşteptare circulară. Acest fenomen este cunoscut<br />
sb mai multe denumiri: impas, interblocare, deadlock, deadly embrace... Un astfel de<br />
fenomen poate să ducă la un blocaj al sistemului sau la distrugerea unor procese.<br />
În 1971, Coffman, Elphic şi Shoshani au indicat patru condiţii necesare pentru<br />
apariţia impasului:<br />
- procesele solicită controlul exclusiv asupra resurselor pe care le cer( condiţia de<br />
excludere mutuală)<br />
- procesele păstrează resursele deja ocupate atunci când aşteaptă alocarea altor<br />
resurse( condiţia de wait for)<br />
- resursele nu pot fi şterse de către procesele care le ţin ocupate până când ele nu<br />
sunt utilizate complet( condiţia de nepreempţie)<br />
- există un lanţ de procese în care fiecare dintre ele aşteaptă o resursă ocupată de<br />
un alt proces din lanţ( condiţia de aşteptare circulară).<br />
Modelarea matematică a impasului. Fie n procese şi m tipuri de resurse.<br />
Procesele se vor nota cu i, i=1,n, iar resursele cu j, j=1,m. Se mai folosesc următoarele<br />
notaţii:<br />
x[j] cantitatea din resursa j existentă în sistem<br />
c[i,j](t) cantitatea din resursa j cerută de procesul i la momentul t<br />
a[i,j](t) cantitatea din resursa j alocată procesului i la momentul t<br />
r(j)(t) cantitatea din resursa j liberă la momentul t<br />
Definiţia 2.1.4.1. Se numeşte stare realizabilă a alocării resurselor la momentul t<br />
dacă au loc condiţiile:<br />
a) fiecare proces cere cel mult câte resurse sunt în sistem, adică<br />
c[i,j](t) x[j], i, j;<br />
b) fiecare proces are alocate cel mult atâtea resurse câte a cerut, adică<br />
a[i,j](t) c[i,j](t), i, j;<br />
c) nu se poate depăşi volumul total de resurse, adică<br />
a[1,j](t)+ a[2,j](t)+...+ a[n,j](t) x[j], j.<br />
Definiţia 2.1.4.2. O succesiune S[1], S[2],..., S[n] a celor n procese se numeşte<br />
sănătoasă la momentul t dacă cererea unui proces S[i] la momentul t nu este împiedicată<br />
de cererile proceselor precedente, de propriile resurse alocate şi de resursele disponibile,<br />
adică pentru i şi j<br />
c[S[i], j](t) a[S[1],j](t)+a[S[2],j](t)+...+a[S[i-1],j](t)+ a[S[i],j](t)+r[j](t).<br />
Definiţia 2.1.4.3. O succesiune S[1], S[2],..., S[n] a celor n procese se numeşte<br />
succesiune fiabilă dacă pentru i şi j<br />
max{c[S[i], j](t)| t0} a[S[1],j](t)+a[S[2],j](t)+...+a[S[i-1],j](t)+<br />
a[S[i],j](t)+r[j](t).<br />
Teorema 2.1.4.1. Dacă la un moment dat t există o succesiune sănătoasă, iar după<br />
acest moment procesele nu mai cer resurse, atunci există o succesiune de stări realizabile<br />
astfel încât toate cererile de resurse ale proceselor să fie satisfăcute. În caz contrar, este<br />
posibilă apariţia impasului.
- 48 -<br />
Teorema 2.1.4.2. Dacă există o succesiune fiabilă( adică cererea maximă a<br />
fiecărui proces este cunoscută în prealabil), atunci există o succesiune de stări realizabile<br />
astfel încât cererile de resurse ale proceselor să fie satisfăcute. În caz contrar este posibilă<br />
apariţia impasului.<br />
În cazul sistemelor de operare, trebuie să se dea rezolvări cel puţin la una din<br />
următoarele trei probleme: ieşirea din impas, detectarea unui impas, prevenirea apariţiei<br />
impasului. Cele două teoreme dau condiţii prin care este indicată eventuala apariţie a unui<br />
impas, dar nu dau metode pentru rezolvarea lui.<br />
Problemele impasului şi rezolvarea lor<br />
a) Ieşirea din impas se rezolvă prin una din următoarele trei strategii:<br />
- reîncărcarea sistemului de operare<br />
- alegerea unui proces victimă, care este fie cele care a provocat impasul fie altul<br />
de importanţă mai mică; se distruge acest proces şi toţi descendenţii lui<br />
- crearea unui punct de reluare, care este o fotografie a memoriei pentru<br />
procesul victimă şi pentru cele cu care acesta colaborează; se distruge apoi procesul<br />
victimă şi descendenţii lui; procesul victimă se reia ulterior.<br />
b) Detectarea unui impas se face atunci când SO nu are un mecanism de<br />
prevenire a impasului. Pentru a reuşi detectarea impasului SO trebuie să aibă o evidenţă<br />
pentru fiecare proces a resurselor ocupate respectiv cerute şi neprimite. Pentru aceasta se<br />
foloseşte graful alocării resurselor. Se face ipoteza că fiecare resursă din sistem se află<br />
într-un singur exemplar; fie R 1 ,..., R m resursele şi P 1 ,...,P n procesele din sistem. Graful<br />
alocării resurselor este G=(X, U), unde X={R 1 ,..., R m , P 1 ,..., P n }, (P i , R j ) U dacă<br />
procesul P i aşteaptă să ocupe resursa R j , iar (R j , P i )U dacă procesul P i ocupă resursa R j .<br />
Teorema 2.1.4.3. Dacă graful (X, U) definit mai sus este ciclic, atunci apare<br />
impasul.<br />
Demonstraţia teoremei se face prin inducţie. Detectarea ciclicităţii grafului se face<br />
printr-un algoritm simplu:<br />
while xX astfel încât x nu are ieşiri( nu (x,y)U) do<br />
begin<br />
şterge x din X; şterge arcele (y, x) U<br />
end;<br />
Dacă în urma ştergerilor se ajunge la graful vid, atunci graful iniţial este aciclic.<br />
Dacă graful obţinut nu este vid atunci el conţine cel puţin un ciclu şi în graful rămas după<br />
reduceri se află procesele şi resursele ce au provocat impasul şi se poate încerca ieşirea<br />
din impas prin metodele prezentate anterior.<br />
c) Prevenirea impasului se face prin trei metode.<br />
Metoda 1, “totul sau nimic”. Procesul trebuie să ceară toate resursele în<br />
momentul încărcării lui; SO întocmeşte graful alocării resurselor ţinând cont de ceea ce<br />
cere procesul candidat la încărcare; dacă graful obţinut este ciclic procesul nu va fi<br />
încărcat. Metoda nu este avantajoasă deoarece procesul trebuie să aştepte până are toate<br />
resursele disponibile şi apoi ocupă resursele permanent deşi s-ar putea să nu aibă nevoie<br />
de ea pe toată durata existenţei lui.
- 49 -<br />
Metoda 2, cererea de resurse într-o anumită ordine. În acest caz resursele<br />
sistemului sunt numerotate; procesele nu trebuie să-şi declare pretenţiile la încărcare, dar<br />
cererile de resurse trebuie să fie făcute în ordinea numerotării lor.<br />
Metoda 3, alocare şi suspendare controlată. Procesul este lansat în execuţie chiar<br />
dacă nu are toate resursele disponibile; el declară la început toate resursele care îI sunt<br />
necesare, iar alocarea lor se face controlat pentru a evita impasul( înainte de a se aloca o<br />
resursă se verifică iminenţa apariţiei impasului; dacă resursa este unicat se verifică<br />
ciclicitatea grafului de alocare a resurselor). Cel mai cunoscut algoritm pentru alocarea<br />
resurselor este algoritmul bancherului, algoritm datorat lui Dijkstra:<br />
var B: boolean;<br />
for i:=1 to n se marchează P i ca neactiv;<br />
for k:=1 to n do<br />
begin<br />
repeat<br />
if nu există procese neactive then<br />
begin<br />
execută S[1],..., S[k-1] până se eliberează resurse;<br />
se trece un proces din aşteptare în activ<br />
end<br />
else<br />
se alege un proces Pi neactiv;<br />
B:= S[1], ..., S[k-1], Pi este o succesiune fiabilă;<br />
if not B then<br />
se pune în aşteptare Pi<br />
else<br />
begin<br />
marchează P i ca activ ; S[k]:= P i<br />
end<br />
until B;<br />
end;<br />
2.1.5. Procese sub UNIX<br />
Crearea proceselor sub UNIX; comunicarea între procese.<br />
Specificarea concurenţei sub UNIX se face cu ajutorul funcţiilor “C” fork, exit,<br />
exec şi wait, apelul acestor funcţii reprezentând apeluri sistem.<br />
Funcţia fork() are ca efect copierea într-o zonă de memorie liberă a<br />
imaginiiprocesului curent şi apoi crearea şi lansarea în execuţie a unui nou proces;<br />
procesul care execută fork() se numeşte tată, iar cel care se creează se numeşte fiu; are<br />
loc o dublă execuţie a instrucţiunilor ce urmează după fork(). Toate fişierele deschise de<br />
către procesul tată sunt accesibile şi în procesele fii în acest fel realizându-se<br />
comunicarea între procese. Funcţia fork() întoarce valoarea 0 în procesul fiu şi o valoare<br />
întreagă nenulă numită pid( Process IDentity= nr. dat de sistem procesului) în procesul<br />
tată. În secvenţa ce urmează se lansează două procese concurente:<br />
if( fork()==0)
- 50 -<br />
{. . . instrucţiuni ale procesului fiu. . .}<br />
else<br />
{ . . . instrucţiuni ale procesului tată . . .}<br />
Funcţia exit(stare) provoacă terminarea unui proces; sunt închise toate fişierele<br />
deschise de către acest proces şi se transmite controlul la procesul părinte. În stare, care<br />
este un întreg se transmite părintelui modul de terminare al procesului.<br />
Funcţia wait( stare) are rol de a aştepta terminarea procesului indicat de stare.<br />
Execuţia secvenţei din graful de precedenţă, fig.2, paragraful 2.1.1. se poate scrie<br />
în “C” astfel:<br />
S1;<br />
n=fork();<br />
if(n==0)<br />
{ S2; S4; m=fork();<br />
if(m==0)<br />
{ S5; exit(p);}<br />
else<br />
{ S6; exit(q);}<br />
}<br />
else<br />
{ S3;<br />
wait(p);<br />
wait(q);<br />
S7;<br />
}<br />
În plus, UNIX oferă funcţiile de forma exec*(nume, . . .) care provoacă în diverse<br />
variante încărcare programului nume peste procesul curent şi lansarea lui în execuţie.<br />
Prin aceste funcţii se pot lansa în execuţie programe care să folosească fişierele oferite de<br />
către procesul părinte. Funcţiile exec* sunt execl, execv, execle, execlv.<br />
În afară de modul de comunicare oferit de funcţia exit la terminarea unui proces,<br />
mai există şi posibilitatea unor apeluri sistem prin intermediul funcţiei signal. Prin acest<br />
apel se provoacă o întrerupere software şi el se face doar în situaţii de excepţie; apelul<br />
signal contează ca o terminare anormală a procesului.<br />
Tot un mod de comunicare între procese este mecanismul pipe şi începând cu<br />
UNIX System V este implementat şi mecanismul semafor.<br />
Gestiunea proceselor UNIX. Conceptul de proces sub UNIX este mai general<br />
decât sub alte SO. În momentul în care un utilizator dă o comandă componenta shell<br />
crează prin fork un nou proces, iar prin exec lansează comanda cerută.<br />
Pentru ca nucleul să gestioneze un proces el trebuie să deţină informaţii despre<br />
procesul respectiv; aceste informaţii sunt reţinute în două zone: tabela de procese şi<br />
structura utilizator.<br />
Tabela de procese conţine următoarele informaţii:<br />
- identificatorul procesului( un număr)<br />
- identificatorul utilizatorului<br />
- lungimea procesului
- 51 -<br />
- locul unde este procesul rezident la momentul curent( în memorie sau pe disc)<br />
Structura utilizator se crează în interiorul nucleului odată cu crearea procesului,<br />
nu poate fi accesată de către utilizator şi conţine:<br />
- zona de salvare a regiştrilor generali<br />
- informaţiile prin care se permite accesul la toate fişierele folosite<br />
- informaţii despre directorul curent.<br />
La evacuarea temporară pe disc a procesului se salvează zona de date şi<br />
instrucţiuni a procesului, conţinutul stivei, structura utilizator după ce s-a memorat în ea<br />
conţinutul regiştrilor generali.
- 52 -<br />
2.2. GESTIUNEA MEMORIEI<br />
2.2.1. Structură; calcul de adrese; protecţie<br />
Pentru a fi executat un program are nevoie de o anumită cantitate de memorie; în<br />
multiprogramare este necesar ca în memorie să fie prezente simultan mai multe<br />
programe. Fiecare program foloseşte zonele de memorie alocate lui independent de alte<br />
eventuale programe active. În general, pe durata execuţiei unui program necesarul de<br />
memorie variază.<br />
Deoarece spaţiul de memorie este( încă) limitat SO şi SC trebuie să gestioneze în<br />
mod eficient folosirea acestui spaţiu. Problemele legate de gestiunea memoriei sunt<br />
rezolvate la nivelul inferior de către SC extins eventual cu o componentă de management<br />
a memoriei. La nivel superior, rezolvarea se face de către SO în colaborare cu SC.<br />
Principalele obiective ale gestiunii memoriei sunt:<br />
- calculul de translatare a adresei( relocare)<br />
- protecţia memoriei<br />
- organizarea şi alocarea memoriei operative<br />
- gestiunea memoriei secundare<br />
- politici de schimb între proces, memoria operativă şi cea secundară.<br />
Structura ierarhică de organizare a memoriei. În structura actuală, memoria<br />
unui calculator apare ca în figură:<br />
MEMORIE DE ARHIVARE<br />
Memorie externă<br />
MEMORIE SECUNDARĂ<br />
MEMORIE OPERATIVĂ<br />
MEMORIE “CACHE”<br />
Memorie internă<br />
CPU<br />
Memoria “cache” conţine informaţiile care au fost utilizate cel mai recent de<br />
către CPU. Are o capacitate mică, dar cu timp de acces foarte rapid. La fiecare acces,<br />
CPU verifică dacă data se află în memoria cache( dacă da se face schimbul între CPU şi<br />
această zonă) şi abia apoi solicită memoria operativă. Dacă data nu se află în memoria<br />
cache, atunci ea este căutată la nivelele superioare şi ea este adusă împreună cu locaţii<br />
vecine ei astfel încât memoria “cache” să fie plină. La unele sisteme de calcul memoria<br />
“cache” lipseşte.
- 53 -<br />
Memoria operativă conţine programele şi datele pentru toate procesele existente<br />
în sistem. În momentul în care un proces este terminat şi distrus, spaţiul de memorie<br />
operativă pe care l-a ocupat este eliberat şi poate fi ocupat de alt proces. Capacitatea<br />
memoriei operative variază de la 64 Ko la câţiva Mo, iar viteza de acces este foarte mare.<br />
Memoria secundară există la SO care deţin mecanisme de memorie virtuală; este<br />
privită ca o extensie a memoriei operative; suportul ei este discul magnetic, deci accesul<br />
la această memorie este mult mai lent. La calculatoarele IBM-PC din primele serii<br />
memoria maximă disponibilă era de doar 640 Ko. Pentru a elimina această restricţie s-a<br />
introdus conceptul de memorie expandată. Prin acest mecanism mai multe “chip-uri” de<br />
memorie operativă pot să aibă alternativ aceeaşi adresă de memorie; avem de a face cu o<br />
memorie secundară care are ca suport hard tot memoria internă. După apariţia lui 80286<br />
şi a modului de lucru protejat, aceste calculatoare au fost dotate cu memorie extinsă care<br />
permite o adresare naturală a spaţiului de peste 1Mo de memorie.<br />
Memoria de arhivare este gestionată de utilizator şi constă din fişiere, baze de<br />
date ş.a. rezidente pe suporturi magnetice.<br />
Memoria “cache” şi memoria operativă formează memoria internă. Accesul CPU<br />
la acestea se face în mod direct ; pentru ca CPU să aibă acces la datele din memoria<br />
secundară şi de arhivare, acestea trebuie mutate în memoria internă.<br />
În ceea ce priveşte performanţele, viteza de acces, preţul de cost pe unitatea de<br />
alocare şi capacitatea de memorare, acestea scad de jos în sus, de la memoria “cache” la<br />
memoria de arhivare.<br />
Mecanisme de translatare a adresei. Adresarea memoriei constă în realizarea<br />
legăturii între un obiect al programului şi adresa corespunzătoare din memoria operativă a<br />
SC. Fazele prin care trece un program de la textele sursă până la execuţie sunt<br />
următoarele:<br />
Compilare Editare de legături Încărcare Execuţie<br />
S1<br />
MO1<br />
S2<br />
...<br />
...<br />
MO2<br />
...<br />
...<br />
FE<br />
PR<br />
Sn<br />
MOn<br />
OP AM AR AF<br />
TEXTE MODULE FIŞIER PROGRAM<br />
SURSĂ OBIECT EXECUTABIL ÎN MEMORIE<br />
Programatorul se referă la memorie prin intermediul mulţimii obiectelor din<br />
program( OP): nume de variabile, de constante, de etichete, de proceduri ... Prin AF se<br />
notează mulţimea adreselor fizice din memoria operativă la care se află memorate în<br />
timpul execuţiei obiectele program ale utilizatorului. Calculul de adresă este<br />
modalitatea prin care se ajunge de la un OP la AF a lui în execuţie. Acest calcul necesită<br />
trei faze corespunzător celor trei faze ale programului.
- 54 -<br />
Faza de compilare transformă un text sursă Si într-un modul obiect Moi;<br />
corespunzător, numele obiectelor program sunt transformate în numere reprezentând<br />
adresele lor în cadrul modului, AM. Deci prima funcţie de calcul de adresă, c: OP AM<br />
este executată de către compilator sau asamblor.<br />
Faza de editare grupează mai multe module obiect formând un fişier executabil.<br />
Editorul de legături realizează a doua fază a evaluării adresei: se transformă adresele din<br />
cadrul modulelor în adrese relocabile( AR). Funcţia de legare este l: AM AR , iar<br />
particularităţile de evaluare ale acestei funcţii sunt proprii editorului de legături.<br />
Trecerea de la adresa relocabilă la adresa fizică este realizată de către CPU prin<br />
funcţia de translatare( relocare) a adresei, t: AR AF .<br />
Pentru a ilustra principiul de lucru al funcţiei de translatare se va presupune că<br />
fişierul executabil conţine înregistrări formate din câte o instrucţiune de forma:<br />
Ari co a1 a2 . . . an<br />
unde<br />
- Ari este adresa relocabilă a instrucţiunii<br />
- co este codul operaţiei<br />
- a1, a2, ..., an sunt argumentele instrucţiunii şi pot fi nume de regiştri, constante<br />
sau adrese relocabile din memorie.<br />
Se presupune că fiecare instrucţiune încape într-o adresă de memorie, între<br />
argumentele a1,..., an există o singură adresă relocabilă, maşina dispune de un singur<br />
registru general A, iar instrucţiunule sunt plasate în locaţii de memorie succesive. În<br />
realitate structura unui fişier executabil este mai complexă, dar considerăm această<br />
structură pentru a ilustra funcţionarea CPU şi a funcţiei de translatare.<br />
Încărcarea unui astfel de fişier în memorie se poate face folosind un încărcător<br />
asemănător lui Loaderabslout prezentat la încărcarea SO.<br />
Se vor folosi următoarele notaţii:<br />
- M[0..m] conţine locaţiile memoriei operative<br />
-pc(Program Counter) indică adresa fizică a instrucţiunii ce urmează a fi executată<br />
- w este conţinutul instrucţiunii curente<br />
- Opcode(w) furnizează codul operaţiei din instrucţiunea curentă( de exemplu 1<br />
pentru adunare, 2 pentru memorare din registrul A într-o anumită locaţie de memorie, 3<br />
pentru salt necondiţionat...)<br />
- Address(w) este o funcţie ce furnizează valoarea adresei relocabile aflată între<br />
argumentele instrucţiunii curente.<br />
Modul de funcţionare a CPU şi de acţiune a funcţiei de translatare este următorul:<br />
pc:= t( adresa_ de _start_a_programului);<br />
repeat<br />
w:= M[pc]; co:= Opcode(w);<br />
adr:= Address(w); pc:=pc+1;<br />
case co of<br />
1: A:= A+ M[t(adr)]; { adunare}<br />
2: M[t(adr)]:= A; { memorare}<br />
3: pc:= t(adr); { salt necondiţionat}<br />
. . .<br />
end { case}<br />
until false;
- 55 -<br />
Există o mare varietate de moduri de adresare; acestea sunt legate de CPU concret<br />
al SC. Se disting însă câteva moduri de adresare uzuale:<br />
- adresare absolută atunci când AR= AF , adică t( x) x,<br />
x AR<br />
- adresare bazată atunci când pentru a obţine o adresă fizică toate adresele<br />
relocabile sunt mărite cu conţinutul registrului de bază Rb( valoarea acestuia este fixată<br />
de către loader sau de către utilizator dacă lucrează în limbaj de asamblare), adică<br />
t( x) ( Rb) x,<br />
x AR .<br />
- adresare indexată atunci când în cadrul instrucţiunii maşină se specifică un<br />
registru de index Ri. Se obţine, printr-o metodă oarecare o adresă provizorie AF1 şi apoi<br />
se obţine adresa definitivă AF2 astfel: AF2: AF1 ( Ri)<br />
. Acest mod de adresare se<br />
foloseşte în special la localizarea elementelor unui tablou.<br />
- adresarea relativă se foloseşte pentru realizarea de salturi într-un program<br />
precizându-se sensul şi numărul de locaţii l( constantă întreagă cu semn) peste care se<br />
sare pentru a se ajunge la noua adresă: AF2: AF1 l.<br />
- adresare indirectă: după ce procesorul obţine o adresă AF1, el interpretează<br />
conţinutul de la AF1 nu ca valoare a unui operand ci ca noua adresă AF2: ( AF1).<br />
Acest<br />
mod de adresare se poate aplica în lanţ şi se aplică în general la invocarea parametrilor<br />
actuali din cadrul unui subprogram.<br />
SC moderne au implementate combinaţii ale acestor metode. Pentru SC care<br />
dispun de memorie virtuală există şi mecanisme mai sofisticate de adresare.<br />
Protecţia memoriei. Fiecare SC respectiv SO trebuie să dispună de mecanisme<br />
care să asigure utilizarea corectă a spaţiului de memorie de către toate procesele<br />
rezidente. Fiecare entitate de memorie alocată(partiţie,pagină,...) conţine o cheie de<br />
protecţie, fiecare entitate de program încărcabilă la un moment dat(segment, pagină,...)<br />
dispune de o cheie de acces. Fiecărei chei de protecţie se asociază un şir de biţi prin care<br />
se specifică posibilităţile zonei respective. Principalele trei posibilităţi sunt R,W şi E:<br />
- R( read-only): din zonă se poate doar citi; se permite executarea instrucţiunilor<br />
maşină care duc date din zonă în regiştri, dar este interzisă memorarea în zona respectivă<br />
a datelor din regiştri. În aceste zone se introduc constantele proceselor.<br />
- W: în zonă se poate scrie; este permisă memorarea în această zonă a datelor din<br />
regiştri. Există două cazuri speciale de scriere: extindere- scriere la sfârşitul zonei şi<br />
ştergere- pregătirea zonei astfel încât următoarea extindere să se facă de la începutul<br />
zonei. Interzicerea posibilităţii W este echivalentă cu posibilitatea R.<br />
- E: conţinutul zonei poate fi executat, deci zona respectivă conţine instrucţiuni<br />
maşină care pot fi executate. Conţinutul zonei rămâne neschimbat(este cod reentrant)<br />
fiind interzis proceselor să modifice zona respectivă.<br />
Procesele( sau segmentele de proces) primesc la încărcare un şir de biţi ce<br />
reprezintă drepturi de acces şi sunt în corespondenţă cu biţii reprezentând posibilităţile<br />
zonelor de memorie.<br />
Protecţia memoriei se face executând doi paşi:<br />
- la fiecare invocare a unei locaţii de memorie se compară cheia de protecţie cu<br />
cea de acces; în caz de neconcordanţă accesul este interzis şi procesul se încheie cu mesaj<br />
de eroare.<br />
- dacă cheile coincid se compară posibilităţile zonei solicitate cu drepturile de<br />
acces ale procesului şi cu acţiunea cerută de proces; accesul este permis dacă comparaţia<br />
se termină cu succes.
- 56 -<br />
Modul concret de implementare a protecţiei memoriei depinde de SC şi SO şi nu<br />
poate fi preluat de la un SC şi SO la altul.<br />
2.2.2. Scheme de alocare a memoriei<br />
Clasificarea tehnicilor de alocare. Problema alocării memoriei se pune în<br />
special la sistemele multiutilizator. Tehnicile de alocare utilizate la diferite SO se împart<br />
în două mari categorii, fiecare înpărţindu-se la rândul ei în subcategorii:<br />
- alocare reală: - la SO monoutilizator<br />
- la SO multiutilizator<br />
- cu partiţii fixe( statică) - absolută<br />
- relocabilă<br />
- cu partiţii variabile( dinamică)<br />
- alocare virtuală - paginată<br />
- segmentată<br />
- segmentată şi paginată.<br />
Alocarea la sistemele monoutilizator. La aceste sisteme este disponibil aproape<br />
tot spaţiul de memorie, iar gestiunea acestui spaţiu cade exclusiv în sarcina utilizatorului<br />
care are la dispoziţie tehnici de suprapunere( overlay) pentru a-şi rula programele mari.<br />
Alocarea memoriei în acest caz este prezentată în figura următoare:<br />
0<br />
a<br />
b<br />
Nucleu SO<br />
Parte<br />
rezidentă<br />
Zona de<br />
suprapunere<br />
Program utilizator<br />
Init<br />
Părţi de suprapus<br />
b b b<br />
Prelucrări<br />
curente<br />
Terminare<br />
c<br />
m<br />
Nefolosit<br />
Porţiunea dintre adresele 0 şi a-1 este rezervată nucleului SO, care rămâne<br />
rezident de la încărcare şi până la oprirea sistemului. Între adresele c şi m-1 ( dacă<br />
memoria are o capacitate de m locaţii) este spaţiul nefolosit de către programul utilizator<br />
curent( adresa c variază de la un program utilizator la altul).<br />
Alocarea cu partiţii fixe. Acest mod de alocare se mai numeşte alocare statică<br />
sau alocare MFT (Memory Fix Tasks). El presupune decuparea memoriei în zone de<br />
lungime fixă numite partiţii. O partiţie este alocată unui proces pe toată durata execuţiei<br />
lui chiar dacă nu o ocupă complet. Un exemplu al acestui mod de alocare este prezentat<br />
în figura următoare( zonele haşurate sunt zonele din partiţii nefolosite de procese):
- 57 -<br />
0<br />
40<br />
86<br />
130<br />
168<br />
190<br />
250<br />
255<br />
Nucleu SO<br />
PR1<br />
PR2<br />
PR3<br />
Partiţia 1<br />
Partiţia 2<br />
Partiţia 3<br />
Alocarea absolută se face pentru programe care sunt pregătite de către editorul de<br />
legături pentru a fi rulate într-o zonă de memorie prestabilită.<br />
La alocarea relocabilă adresarea în partiţie se face cu bază şi deplasament; la<br />
încărcarea unui program în memorie se pune în registrul său de bază adresa de început a<br />
partiţiei. Partiţiile au de obicei lungimi diferite, iar fixarea dimensiunilor partiţiilor este o<br />
problemă dificilă pentru că nu se pot prevedea ce cantităţi de memorie vor solicita<br />
procesele încărcate în aceste partiţii; alegerea unei dimensiuni mai mari scade<br />
probabilitatea ca un proces să fie eliminat din sistem fără a fi executat, dar scade numărul<br />
proceselor active din sistem. Acest mod de alocare se foloseşte de obicei la sistemele<br />
seriale. La fiecare partiţie există un şir de procese care aşteaptă să fie executate. Modul de<br />
organizare al acestui sistem de aşteptare poate influenţa performanţele de ansamblu ale<br />
sistemului şi poate atenua efectul unei eventuale dimensionări defectuoase a partiţiilor.<br />
Există două moduri de legare a proceselor la partiţii:<br />
- fiecare partiţie are o coadă proprie; operatorul stabileşte de la început care sunt<br />
procesele care se vor executa în fiecare partiţie<br />
- există o singură coadă pentru toate partiţiile; SO alege partiţia pentru procesul ce<br />
urmează să intre în execuţie.<br />
Alocarea cu partiţii variabile. Acest mod de alocare se mai numeşte alocare<br />
dinamică sau alocare MVT( Memory Variable Task). În funcţie de solicitările la sistem şi<br />
de capacitatea de memorie încă disponibilă la un moment dat, se modifică automat<br />
numărul şi dimensiunea partiţiilor. În figura următoare se prezintă mai multe stări<br />
succesive ale memoriei în acest tip de alocare:<br />
PR2 FINISH PR4 READY PR1 FINISH PR5 READY<br />
0<br />
40<br />
100<br />
SO<br />
PR1<br />
0<br />
40<br />
100<br />
SO<br />
PR1<br />
0<br />
40<br />
100<br />
SO<br />
PR1<br />
0<br />
40<br />
100<br />
SO<br />
0<br />
40<br />
85<br />
100<br />
PR5<br />
200<br />
200<br />
180<br />
200<br />
180<br />
200<br />
180<br />
200<br />
230<br />
230<br />
230<br />
230<br />
230
- 58 -<br />
PR2<br />
PR4<br />
PR4<br />
PR4<br />
PR3<br />
PR3<br />
PR3<br />
PR3<br />
PR3<br />
a) b) c) d) e)<br />
Atunci când procesul intră în sistem el este plasat în memorie într-un spaţiu în<br />
care încape cea mai lungă ramură a sa; acest spaţiu este format din două partiţii: una în<br />
care se află procesul, iar cealaltă într-un spaţiu liber. În timp numărul spaţiilor libere<br />
creşte, iar dimensiunea lor scade. Fenomenul poartă numele de fragmentarea internă a<br />
memoriei.<br />
În momentul în care pentru un proces nu există spaţiu în care să se încarce, SO va<br />
lua una dintre următoarele decizii:<br />
a) procesul aşteaptă până când i se eliberează o cantitate suficientă de memorie;<br />
b) SO încearcă alipirea unor spaţii libere vecine pentru a se obţine un spaţiu de<br />
memorie suficient de mare; operaţia poartă numele de colaţionare. În figura de mai sus<br />
d), după terminarea procesului PR4 apar trei zone libere adiacente de 15Ko, 80Ko<br />
respectiv 20Ko. SO poate( nu face întotdeauna automat) să formeze un singur spaţiu liber<br />
de 115Ko.<br />
c) SO decide efectuarea unei operaţii de compactare a memoriei( relocare) adică<br />
de deplasare a partiţiilor active către partiţia monitor pentru a absorbi fragmentele de<br />
memorie neutilizate. De regulă compactarea este o operatţie costisitoare şi se aleg soluţii<br />
de compromis:<br />
- lansarea periodică a compactării indiferent de starea sistemului; procesele ce nu<br />
au loc în memorie aşteaptă compactarea sau terminarea unui alt proces.<br />
- realizarea unei compactări parţiale pentru a asigura loc numai procesului care<br />
aşteaptă.<br />
- mutarea unor procese cu colaţionarea spaţiilor libere.<br />
Între alocările de tip MFT şi MVT nu există diferenţe hard. Alocarea MVT este<br />
realizată prin intermediul unor rutine specializate. Alocarea MVT a fost utilizată mai întâi<br />
la sistemele IBM-360 sub SO OS-300 MVT şi apoi la PDP 11/45.<br />
2.2.3. Mecanisme de memorie virtuală<br />
Termenul de memorie virtuală este asociat cu capacitatea de a adresa un spaţiu de<br />
memorie mai mare decât este cel disponibil la memoria operativă a SC. Conceptul a<br />
apărut în 1960 la <strong>Universitatea</strong> din Manchester odată cu SO Atlas.<br />
Există două metode de virtualizare: alocare paginată şi alocare segmentată.
- 59 -<br />
Alocarea paginată. A apărut la diverse SO pentru a elimina fragmentarea<br />
excesivă ce apare la MVT. Acest tip de alocare presupune cinci lucruri:<br />
a) Instrucţiunile şi datele unui program sunt împărţite în zone de lungime fixă<br />
numite pagini virtuale. Fiecare AR aparţine unei pagini virtuale; paginile virtuale se<br />
păstrează în memoria secundară.<br />
b) Memoria operativă este împărţită in pagini de lungime fixă numite pagini fizice<br />
a căror lungime este fixată prin hard. Paginile virtuale şi cele reale au aceeaşi lungime<br />
care este o putere a lui 2 şi care este o constantă a sistemului( 1Ko, 2Ko,...).<br />
c) Fiecare AR este de forma<br />
p<br />
d<br />
unde p este numărul paginii virtuale, iar d este adresa în cadrul paginii.<br />
d) Fiecare AF este de forma<br />
f<br />
d<br />
unde f este numărul paginii fizice, iar d este adresa în cadrul paginii.<br />
e) Calculul funcţiei de translatare t: AR AF se face prin hard conform<br />
următoarei scheme:<br />
Procesor Adresa Tabele de Adresa Memorie<br />
central virtuală pagini fizică operativă<br />
CPU p d f d<br />
p<br />
f<br />
f<br />
d<br />
Dacă se notează prin M[0..m] notăm memoria operativă, prin k puterea lui 2 care<br />
dă lungimea unei pagini, prin TP adresa de start a tabelei de pagini, atunci algoritmul de<br />
calcul al funcţiei t este:<br />
function t(p,d): integer;<br />
begin
- 60 -<br />
if pagina absentă din memoria operativă then EROARE<br />
else<br />
t: M[ TP]<br />
2<br />
k d<br />
end;<br />
Fiecare proces are propria tabelă de pagini în care este trecută adresa fizică a<br />
paginii virtuale dacă ea este prevăzută în memoria operativă. La încărcarea unei noi<br />
pagini virtuale aceasta se depune într-o pagină fizică liberă, deci în memoria operativă<br />
paginile fizice sunt distribuite în general necontiguu între mai multe procese. Se spune că<br />
are loc o proiectare a spaţiului virtual peste cel real.<br />
Acest mecanism are ca avantaj faptul că foloseşte mai eficient memoria operativă,<br />
fiecare program ocupând doar memoria strict necesară la un moment dat. Un alt avantaj<br />
este acela că mai multe programe pot folosi în comun instrucţiunile unei proceduri( o<br />
astfel de procedură se numeşte reentrantă).<br />
Acest tip de alocare este utilizat la SC IBM-PC dotate cu memorie expandată.<br />
Alocare segmentată. În acest caz textul unui program poate fi plasat în zone de<br />
memorie distincte, fiecare conţinând o bucată de program numită segment( spre deosebire<br />
de alocarea reală unde fiecare proces trebuie să ocupe un spaţiu contiguu). Deosebirea<br />
dintre alocarea paginată şi cea segmentată este că segmentele sunt de lungimi diferite. Ca<br />
şi la alocarea paginată, o adresă virtuală este o pereche ( s, d) unde s este numărul<br />
segmentului, iar d este adresa în cadrul segmentului. Fiecare proces activ are o tabelă de<br />
segmentare şi fiecare intrare în tabelă conţine adresa de început a segmentului. Calculul<br />
de adresă se face ca şi la alocarea paginată; dacă la adresa TS se află începutul tabelei de<br />
segmente atunci funcţia t de translatare a adresei este t( s, d) M[ TS s]<br />
d . Avantajele<br />
alocării segmentate sunt( pe lângă altele):<br />
a) se pot crea segmente reentrante care să fie utilizate în comun de către mai<br />
multe procese( dacă aceste procese au în tabelele lor aceeaşi adresă pentru segmentul<br />
pur).<br />
b) se realizează o bună protecţie a memoriei, fiecare segment putând primi alte<br />
drepturi de acces care sunt trecute în tabela de segmente.<br />
Alocare segmentată şi paginată. La alocarea segmentată este posibil să apară<br />
fenomunul de fragmentare ce apare la alocarea cu partiţii variabile. Ideea alocării<br />
segmentate şi paginate este aceea ca alocarea spaţiului pentru fiecare segment să se facă<br />
în pagini. Pentru aceasta fiecare proces activ are propria tabelă de segmente şi fiecare<br />
segment dintre cele încărcate în memorie are propria tabelă de pagini. Fiecare intrare în<br />
tabela de segmente are un câmp rezervat adresei de început a tabelei de pagini proprii<br />
segmentului respectiv. O tabelă pentru segmentare şi paginare are forma:<br />
Tabela de segmente<br />
( una la proces)<br />
Tabela de pagini<br />
( una la segment)<br />
Memoria reală<br />
Tabela de<br />
procese
- 61 -<br />
O adresă virtuală are forma<br />
s p d<br />
unde s este numărul segmentului, p este numărul paginii virtuale în cadrul segmentului,<br />
iar d este deplasamentul în cadrul paginii.<br />
O adresă fizică are forma<br />
f<br />
d<br />
unde f este numărul paginii fizice, iar d este deplasamentul în cadrul paginii.<br />
Dacă k este constanta ce dă dimensiunea unei pagini( 2 k ), TS adresa de început a<br />
tabelei de segmente a unui proces, iar primul câmp al fiecărei intrări din tabela de<br />
segmente este pointerul spre tabela lui de pagini, atunci funcţia t de translatare se<br />
calculează astfel: t( s, p, d) M[ M[ TS s] p]<br />
2 k d .<br />
Acest sistem de alocare este utilizat de către SO MULTICS, SO VAX/VMS.<br />
Calculatoarele IBM-PC cu microprocesor cel puţin 80386 dispun de un mecanism hard<br />
de gestiune paginată şi segmentată a memoriei extinse.<br />
2.2.4. Gestiunea memoriei sub diverse SO<br />
UNIX<br />
Pentru gestiunea memoriei sub SO UNIX trebuie ţinut cont de faptul că un proces<br />
poate să genereze uşor un alt proces şi că există o mare diversitate de SC pe care este<br />
implementat SO UNIX.<br />
Folosind apelurile sistem fork şi exec se pot crea oricâte procese. Dacă la un<br />
moment dat în memorie există două procese A şi B, iar B execută un apel fork, apoi un<br />
exec(C) atunci harta memoriei apare astfel:
- 62 -<br />
KERNEL KERNEL KERNEL<br />
A<br />
A<br />
A<br />
B<br />
B<br />
Fiul lui B<br />
B<br />
C<br />
a) b) c)<br />
În figură, a) este harta memoriei la început, b) după lansarea lui fork, iar c) după<br />
lansarea lui exec.<br />
Aceste modificări ale memoriei nu se fac sub controlul direct al nucleului, rolul<br />
gestiunii aparţine sistemului de operare care are sarcini suplimentare privind gestiunea<br />
memoriei.<br />
Gama mecanismelor de gestiune a memoriei acoperă tot ce se cunoaşte în<br />
domeniu.<br />
Pentru sistemele mici, monoutilizator implementările UNIX sunt foarte simple: nu<br />
se face nici paginare, nici swapping; există o listă prin care sunt înlănţuite spaţiile libere,<br />
iar alocarea se face ca la alocarea cu partiţii variabile.<br />
Pe maşinile PDP mai slabe decât seria PDP11 s-a adoptat tehnica swapping(<br />
evacuare temporară): procesele inactive sunt evacuate şi încărcate pe/de pe disc.<br />
Implementările VAX/UNIX oferă un spaţiu mare de memorie virtuală. Cele mai<br />
multe implementări UNIX actuale adoptă mecanisme de memorie virtuală cu paginare.<br />
Dacă memoria reală este mică se practică evacuare temporară pe disc.<br />
Fiecare adresă virtuală conţine un număr de pagină şi un deplasament în cadrul<br />
paginii. Componenta MMU( Memory Management Unit) a nucleului transformă această<br />
adresă virtuală în adresă reală. Tabela de gestiune a paginilor este plasată în memorii mai<br />
rapide, dacă există. Fiecare intrare în tabela de pagini conţine:<br />
- corespondenţa între pagina virtuală şi cea reală<br />
- un bit de modificare care are valoarea 1 dacă conţinutul paginii a fost modificat<br />
- un bit de accesabilitate prin care sistemul află dacă într-un interval de timp fixat<br />
de sistem pagina a fost sau nu în memorie<br />
- biţii de protecţie etc.<br />
MS-DOS<br />
Calculatoarele compatibile IBM-PC dispun de obicei de 640 Ko memorie RAM<br />
disponibilă utilizatorului; la acest tip de SC este permisă adresarea a maximum 1 Mo<br />
memorie. SO DOS poate adresa direct 384 Ko. Memoria RAM este împărţită în două<br />
părţi:<br />
- memoria convenţională aflată între adresele 00000 şi 9FFFF( cei 640 Ko<br />
disponibile utilizatorului)
- 63 -<br />
- memoria rezervată( ascunsă, shadow) aflată între adresele A0000 şi FFFFF.<br />
Gestionarea memoriei convenţionale. Porţiunea RAM gestionată de DOS se<br />
împarte în două zone:<br />
- zona sistem: începe de la adresa 0 şi conţine:<br />
- vectorul de întreruperi<br />
- driverele interne<br />
- driverele declarate în CONFIG.SYS<br />
- bufferele disc<br />
- partea rezidentă din COMMAND<br />
- zona TPA ce conţine restul programelor lansate în sistem.<br />
Programele DOS acceptă trei tipuri de segmente: de cod, de date şi de stivă. Un<br />
segment poate avea cel mult 64 Ko. Programele executabile sub DOS sunt de două tipuri:<br />
EXE şi COM. Un program de tip COM are cel mult 64 Ko şi este format dintr-un singur<br />
segment care este în acelaşi timp segment de cod, date şi stivă. Un program de tip EXE<br />
poate fi oricât de mare, poate conţine oricâte segmente care pot ocupa orice locuri în zona<br />
TPA. Deci se poate considera că se foloseşte alocarea segmentată, dar nepaginată.<br />
Unitatea de alocare a memoriei DOS este paragraful care este o porţiune de 16<br />
octeţi şi începe la o adresă multiplu de 16. Controlul spaţiilor de memorie TPA se face<br />
folosind aşa-numitele MCB-uri( Memory Control Block). Un MCB are 16 octeţi şi<br />
conţine:<br />
- un octet de control; toate MCB-urile cu excepţia ultimului au în acest octet codul<br />
ASCII al caracterului M, ultimul are codul lui Z şI marchează sfârşitul listei înlănţuite de<br />
MCB-uri( Mark Zbirkovski)<br />
- pointer( adresă de segment pe 2 octeţi) spre începutul programului părinte al<br />
zonei de memorie ce urmează<br />
- dimensiunea în paragrafe a zonei ce urmează şi care aparţine programului.<br />
O zonă controlată de un MCB conţine un segment al unui program; imediat ce se<br />
termină o zonă controlată de un MCB urmează un alt MCB care controlează o zonă<br />
ocupată de de acelaşi program, de un alt program sau o zonă liberă.<br />
Sub DOS există programe care după terminarea lor rămân instalate în meorie şI<br />
pot fi reactivate în orice moment( TSR-uri Terminate and Stay Resident).<br />
Pentru a se vizualiza organizarea şi ocuparea memoriei DOS se poate folosi<br />
pogramul MEM. Sintaxa de apel este MEM [/p ¦ /d ¦ /c]. Apelat simplu afişează<br />
dimensiunea memoriei convenţionale şi a spaţiului liber. Cu opţiunile p sau d se afişează<br />
adresele şi lungimile zonelor ocupate de diverse programe, numele şi tipul lor. Opţiunea c<br />
dă doar numele şi lungimile programelor din memoria convenţională.<br />
Gestiunea memoriei rezervate. În această zonă DOS îşi rezervă spaţiul necesar<br />
memoriei ecran şi extensiilor acesteia, sunt memorate o serie de componente BIOS şi aici<br />
se află o fereastră de 64 Ko folosită pentru exploatarea memoriei expandate.<br />
Începând cu 1985, sub tutela firmelor Lotus, Intel şi Microsoft s-au elaborat<br />
standarde de folosire sub DOS a unei memorii RAM mai mari de 1 Mo:<br />
- standardul de memorie expandată( EMS) este aplicabil în primul rând maşinilor<br />
cu microprocesor 8086 şI 8088. Principiul lui de bază se numeşte “comutare bank” şi<br />
constă în următoarele: în memorie există mai multe “chip”- uri totalizând până la 8 Mo
- 64 -<br />
care pot ocupa pe rând o aceeaşi adresă aflată în spaţiul de adrese de până la 1 Mo.<br />
Mecanismul de comutare( EMM) foloseşte în acest scop o fereastră de 64 Ko liberă în<br />
memorie rezervată.<br />
- standardul de memorie extinsă( XMS) este aplicabil începând cu maşinile 80286<br />
şi prevede existenţa mai multor chip-uri totalizând până la 16 Mo; fiecare chip are adresă<br />
fixă în spaţiul celor 16 Mo. Pentru programele obişnuite de aplicaţii care “nu văd” un<br />
spaţiu de peste 1 Mo există managerul soft XMM care permite copierea de blocuri de<br />
memorie din spaţiile de peste 1Mo în fereastra de 64 Ko din memoria rezervată şi invers.<br />
În acest mod orice program poate să adreseze un spaţiu de memorie oricât de mare.
- 65 -<br />
2.3. Fişiere şi gestiunea fişierelor<br />
Gestiunea fişierelor este serviciul cel mai vizibil oferit utilizatorului de către SO. SC<br />
poate memora informaţiile, le poate imprima pe hârtie sau afişa pe ecran. Se va prezenta în<br />
continuare situaţia în care memorarea se face pe suport magnetic.<br />
2.3.1. Gestiunea fişierelor din punctul de vedere al utilizatorului<br />
Se numeşte volum o rolă de bandă, un ansamblu formând un disc de masă, un harddisc,<br />
un disc flexibil. În cadrul unui volum informaţiile sunt grupate da către SO la indicaţia<br />
utilizatorului în fişiere. Prin programele sale utilizatorul are acces la un moment dat numai la o<br />
entitate din cadrul unui fişier, entitate numită articol sau înregistrare.<br />
Exemplu: presupunem că informaţiile ce compun un fişier se referă la datele personale<br />
ale studenţilor dintr-o facultate; un articol este format din datele referitoare la un student; există<br />
atâtea articole câţi studenţi sunt în facultate.<br />
Informaţiile dintr-un articol sunt grupate în subdiviziuni numite câmpuri sau atribute.<br />
Fiecare câmp al unui articol are în fişier o valoare. Perechea (câmp, valoare) se numeşte cheie.<br />
Un index de articol este un atribut cu proprietatea că pentru orice două articole valorile atributului<br />
sunt diferite. Un fişier poate avea unul sau mai mulţi indecşi.<br />
Exemplu: un articol dintr-un fişier de tipul din exemplul anterior ar putea avea câmpurile:<br />
- nume<br />
- prenume<br />
- nr_matricol<br />
- data_naşterii<br />
- loc_naştere<br />
- adresa<br />
- buletin<br />
- secţia<br />
- note<br />
Perechea ( nume, “Popescu”) este o cheie; perechea ( nr_matricol, 4221) este un index, la fel<br />
perechea ( buletin, BT312412).<br />
Lungimea de reprezentare a unui articol poate fi aceeaşi pentru toate articolele din fişier<br />
sau poate varia; corespunzător avem articole cu format fix şi articole cu format variabil.<br />
Lungimea maximă de reprezentare a unui articol nu poate fi oricât de mare, deoarece într-un bloc<br />
de informaţie trebuie să intre mai multe articole.<br />
Un sistem de gestiune a fişierelor( SGF) este un ansamblu de rutie de legătură între<br />
utilizator şi componenta de I/O la nivel fizic pentru operarea cu fişiere. Utilizatorul are la<br />
dispoziţie o serie de primitive pe care le poate solicita SGF-ului pentru servicii referitoare la<br />
fişiere. Acţiunile SGF se pot grupa pe 4 niveluri:<br />
- nivel de câmp şi index<br />
- nivel de articol<br />
- nivel de fişier<br />
- nivel de volum.<br />
Conceptul de fişier. Există mai multe definiţii pentru noţiunea de fişier, dar înţelegerea<br />
corectă a acestei noţiuni este intuitivă. S-ar putea defini fişierul ca:<br />
- ansamblu de informaţii definite de către creatorul său<br />
- colecţie de date ce poartă un nume
- 66 -<br />
- ansamblu de elemente( numite articole) grupate şi având ca scop controlul accesului,<br />
regăsirea şi modificarea elementelor.<br />
S-ar putea da o definiţie abstractă a fişierului: un fişier f este o funcţie f:NT unde N<br />
este mulţimea numerelor naturale, iar T mulţimea valorilor posibile pentru un tip de date deja<br />
definit; iN indică numărul de ordine al unui articol din fişier.<br />
Operaţii asupra unui fişier. Fie f un fişier cu n articole. Operaţiile asupra fişierului f se<br />
pot descrie astfel:<br />
Citirea( Read) articolului k din fişier înseamnă obţinerea valorii f(k).<br />
Scrierea( Write) înseamnă adăugarea unui nou articol la fişier; în acest caz fişierul f se<br />
transformă într-un fişier f’ definit astfel:<br />
n:=n+1; f’(i):=f(i), i=1,n; f’(n+1):=x,unde x este valoarea articolului ce se introduce.<br />
Inserarea( Insert) unui nou articol cu valoarea x după articolul cu numărul de ordine k<br />
înseamnă obţinerea unui nou fişier f’ cu n+1 articole definit astfel:<br />
f’(i):=f(i), i=1,k; f’(k+1):=x; f’(i+1):=f’(i), i=k+1,n.<br />
Stergerea( Delete) articolului cu numărul de ordine k înseamnă obţinerea unui nou fişier<br />
f’ cu n-1 articole definit astfel:<br />
f’(i):=f(i), i=1,k-1; f’(i):=f(i+1), i=k,n-1;<br />
Modificarea( Modify) articolului cu numărul de ordine k înseamnă obţinerea unui nou<br />
fişier f’ cu n articole definit astfel:<br />
f’(i):=f(i), i=1,k-1; f’(k):=x; f’(i):=f’(i), i=k+1,n.<br />
Practic, prin aceste operaţii nu se crează întotdeauna un nou fişier. SO acţionează asupra<br />
informaţiilor de pe suport şi lasă nemişcate articolele neimplicate.<br />
Tipuri de acces la articolele unui fişier la o operaţie de citire.<br />
- acces secvenţial la un articol f(i): presupune efectuarea a i-1 accese, în ordine la<br />
articolele cu numerele 1, 2,..., i-1.<br />
- acces direct( random acces) la un articol: presupune existenţa unui mecanism de acces<br />
fără parcurgerea articolelor ce îl preced. Există două moduri de acces direct:<br />
- acces prin număr de poziţie( adresă): se dă sistemului valoarea i şi acesta<br />
întoarce valoarea f(i)<br />
- acces prin conţinut: se dă sistemului o cheie (a,v) şi acesta întoarce articolul i<br />
pentru care f(i).a=v<br />
Tipuri de fişiere. Clasificarea fişierelor se poate face după mai multe criterii:<br />
1) După lungimea unui articol<br />
- fişiere cu articole de format fix<br />
- fişiere cu articole de format variabil: fiecare articol are propria lungime de<br />
reprezentare, sfârşitul articolului se marchează prin octeţi cu conţinut special. Articolele pot avea<br />
şi o parte fixă.<br />
2) După posibilitatea de afişare sau tipărire a conţinutului:<br />
- fişiere text: conţinutul lor poate fi tipărit. Un astfel de fişier este o succesiune de<br />
octeţi fiecare reprezentând codul unui caracter tipăribil. O linie este un şir de caractere ce se<br />
termină printr-un separator de linii( CR/LF). Sfârşitul fişierului se marchează prin caracterul<br />
funcţional EOF.<br />
- fişiere binare: sunt formate din şiruri de octeţi consecutivi fără nici o<br />
semnificaţie pentru afişare; semnificaţia fiecărui octet fiind internă. De exemplu, fişierele obiect<br />
rezultate din compilare sunt fişiere binare, la fel şi cele executabile rezultate în urma editării de<br />
legături.<br />
3) După suportul pe care este rezident fişierul:<br />
- fişiere pe disc magnetic<br />
- fişiere pe bandă sau casetă<br />
- fişiere pe imprimantă<br />
- fişiere tastatură
- 67 -<br />
- fişiere pe ecran<br />
- fişiere pe bandă de hârtie<br />
- fişiere pe plotter, digitizor ş.a.m.d.<br />
Nu toate aceste fişiere acceptă orice tip de operaţie şi nici orice tip de acces. Acces direct acceptă<br />
doar fişierele pe disc, celelalte acceptă doar acces secvenţial. Fişierele tastatură acceptă numai<br />
citire, cele pe imprimantă, plotter sau ecran, numai scriere.<br />
4) După modurile de acces permise de către fişier se disting două tipuri: fişiere<br />
secvenţiale şi fişiere în acces direct. Fişierele secvenţiale permit numai accesul secvenţial; toate<br />
fişierele care au alt tip de suport decât discul magnetic sunt fişiere secvenţiale. Fişierele în acces<br />
direct permit accesul direct cel puţin în citire. Limbajele de programare Pascal, „C‟... dispun de<br />
mecanisme prin care se pot realiza fişiere în acces direct prin număr de poziţie. Unele limbaje sau<br />
SO au mecanisme ce permit accesul direct prin conţinut( organizări evoluate ale fişierelor). Dintre<br />
acestea cele mai importante sunt fişierele organizate: secvenţial indexat, selectiv, multilistă,<br />
inverse, folosind B-arbori.<br />
Referirea la un fişier se face în funcţie de regulile sintactice impuse de către SO. În<br />
general referirea se face printr-un şir de caractere( fără spaţii) ce conţine cinci zone:<br />
Periferic : Cale Nume . Tip ; Versiune<br />
Sintaxa concretă cerută de fiecare SO particular foloseşte numai unele dintre aceste zone:<br />
SO Periferic Cale Nume Tip Versiune<br />
RSX da da 9 caractere 3 caractere da<br />
UNIX - da 14 caractere - -<br />
CP/M da - 8 caractere 3 caractere -<br />
MS_DOS da da 8 caractere 3 caractere -<br />
Periferic indică numele perifericului suport al fişierului, nume impuse de către SO.<br />
Cale desemnează subdirectorul din cadrul discului unde se află fişierul. Pentru RSX calea<br />
se specifică prin UIC sub forma [g,m]. În absenţa căii SO ia în considerare o cale implicită, UICul<br />
implicit pentru RSX sau directorul implicit pentru UNIX şi MS_DOS.<br />
Nume este un şir de litere şi cifre date de creatorul fişierului.<br />
Tip sau Extensie a numelui este dat tot de către utilizator şi reflectă conţinutul fişierului.<br />
Fiecare SO cere de obicei o extensie standard la anumite tipuri de fişiere. Iată câteva tipuri de<br />
fişiere şi modul în care sunt ele specificate în cele trei SO:<br />
RSX CP/M MS_DOS Tip de fişier<br />
BAS BAS BAS Text sursă BASIC<br />
FTN FOR FOR Text sursă FORTRAN<br />
PAS PAS PAS Text sursă PASCAL<br />
C C C Text sursă „C‟<br />
CBL<br />
Text sursă COBOL<br />
MAC ASM ASM Fişier sursă în limbaj de asamblare<br />
OBJ REL OBJ Fişier obiect rezultat al unei compilări<br />
TSK COM EXE COM Fişier executabil, rezultat al unei editări de legături<br />
CMD SUB BAT Fişier de comenzi<br />
LST PRN LST Fişier listing<br />
DAT DAT DAT Fişier de date<br />
DOC DOC DOC Fişier text conţinând documentaţii<br />
TXT TXT TXT Fişier text oarecare<br />
MAP MAP Fişier de alocare la editarea de legături
- 68 -<br />
DIR<br />
Fişier director<br />
ODL<br />
Text conţinând descrierea reacoperirii<br />
OLB REL LIB Fişier bibliotecă de module obiect<br />
TMP $$$ TMP Fişier temporar<br />
BAK BAK Fişierul vechi după editarea unui text<br />
Versiune este o noţiune proprie RSX şi diferenţiază mai multe versiuni ale aceluiaşi fişier.<br />
2.3.2. Acţiunile SGF la nivel de articol<br />
După cum s-a specificat în paragraful anterior, în practică, la operaţiile de scriere,<br />
inserare, modificare, nu se creează un nou fişier, ci SGF acţionează numai asupra articolelor în<br />
cauză.<br />
În funcţie de suportul fişierului, operaţiile permise fizic sunt:<br />
- citire, pentru suporturile disc, bandă magnetică, bandă de hârtie, cartele, tastatură,<br />
digitizor<br />
- scriere, pentru suporturile disc, bandă magnetică, bandă de hârtie, ecran, imprimantă,<br />
plotter<br />
- inserare, ştergere, modificare, pentru suporturile de tip disc.<br />
Scrierea şi actualizarea fişierelor disc. Suportul disc permite scriere şi citire în acelaşi<br />
timp. Operaţiile de scriere, inserare, ştergere şi modificare se derulează diferit în funcţie de<br />
formatul articolelor şi de faptul că fişierul este secvenţial sau nu.<br />
Pentru fişiere secvenţiale se procedează în felul următor:<br />
- scrierea se desfăşoară în mod firesc<br />
- modificarea se face prin rescrierea articolului nou peste cel vechi; celelalte articole<br />
trebuie să rămână nemişcate de la locul lor. Acest lucru este posibil numai dacă articolele sunt de<br />
lungime fixă.<br />
- ştergerea se face prin invalidare, fără ca articolul să elibereze zona fizică pe care o<br />
ocupă. SGF adaugă la fiecare articol un octet numit indicator de ştergere care are valoarea 1 dacă<br />
articolul există pentru SGF şi 0 dacă este ignorat( se consideră şters); pentru a evita ocuparea unui<br />
spaţiu fizic considerabil se recomandă ca din când în când fişierul să fie recreat pentru a elibera<br />
spaţiul fizic ocupat de articolele şterse.<br />
- inserarea unui articol trebuie făcută în aşa fel încât celelalte articole să rămână<br />
nemişcate; acest fapt este posibil numai dacă articolele sunt legate printr-o listă înlănţuită care<br />
permite ca două articole să fie vecine logic chiar dacă ocupă spaţii fizice îndepărtate.<br />
Pentru fişierele în acces direct operaţiile se desfăşoară în mod similar. De regulă sunt<br />
permise a se efectua în acces direct toate cele patru operaţii. Există însă unele organizări de fişiere<br />
în acces direct care permit operaţia de citire numai în acces secvenţial.<br />
Blocarea şi deblocarea articolelor. Pentru a prezenta aceste concepte să revenim la<br />
împărţirea unui fişier în blocuri( pagini, înregistrări fizice). Un bloc este unitatea de schimb între<br />
suportul fişierului şi memoria internă.; lungimea lui este delimitată da capacitatea memoriei<br />
disponibile. Un bloc conţine unul sau mai multe articole. SO RSX, UNIX, CP/M, MS_DOS au<br />
dimensiunea unui bloc disc fixată la generarea sistemului. SGF sub RSX, CP/M, MS_DOS<br />
utilizează conceptul de articol în timp ce UNIX defineşte un fişier ca un şir de octeţi, fiecare octet<br />
este adresabil în cadrul fişierului, deci un articol este format dintr-un octet; fişierul este în blocuri<br />
de câte 512 octeţi.<br />
La nivel fizic, fiecare SO vede fişierul ca o succesiune de blocuri. Prin intermediul SGF<br />
se realizează gruparea mai multor articole într-un bloc la operaţia de scriere- blocarea articolelorşi<br />
operaţia inversă la citire- deblocarea articolelor. Prin aceste operaţii se efectuează câte o citire<br />
sau scriere fizică la fiecare bloc de articole, nu la fiecare articol.
- 69 -<br />
Se presupune în continuare pentru simplificare că se lucrează numai cu fişiere secvenţiale<br />
şi numai cu operaţii de citire şi scriere. Algoritmii de blocare şi deblocare se vor descrie în<br />
continuare prin procedurile Get şi Put. În practică un bloc de informaţie începe cu un antet de<br />
bloc ce conţine câţiva octeţi cu informaţii ce caracterizează blocul( de exemplu lungimea<br />
informaţiilor utile din bloc). După antet urmează articolele unul după altul. Dacă antetul lipseşte<br />
atunci constanta LAT va avea valoarea zero. Analog, un articol poate să înceapă cu un antet de<br />
articol format din octeţi ce caracterizează articolul( octetul indicator de ştergere, lungimea<br />
articolului,...). Dacă antetul lipseşte constanta LAA va avea valoarea zero. Parametrul la conţine<br />
lungimea efectivă a articlului, fără antet, iar parametrul za conţine articolul efectiv, fără antet.<br />
Utilizatorul comunică cu SGF numai prin intermediul acestor doi parametri. Se mai folosesc<br />
pentru descrierea blocării şi deblocării două proceduri şi două funcţii cu semnificaţiile:<br />
Procedure Puneantett( var Z: tampon; l: integer); prin care se depune la începutul zonei<br />
Z un antet de bloc ce cuprinde l octeţi de informaţie, inclusiv antetul de bloc.<br />
Procedure Puneanteta(Z: tampon;i,l:integer); prin care se depune în zona Z începând cu<br />
poziţia i un antet de articol; articolul are o lungime totală, inclusiv antetul,de l octeţi.<br />
Function Scoateantett( Z: tampon): integer; întoarce, plecând de la antetul blocului aflat<br />
în zona Z, lungimea totală a blocului, inclusiv antetul de bloc.<br />
Function Scoateanteta( Z: tampon; i: integer): integer; întoarce lungimea totală a<br />
articolului, inclusiv antetul, aflat în blocul Z, începând de pe poziţia i.<br />
const<br />
LAA=...;{ lungimea antetului de articol}<br />
LAT=...;{ lungimea antetului de bloc}<br />
LMAXA=...;{ lungimea maximă a unui articol}<br />
LMAXT=...;{ lungimea zonei tampon care coincide cu lungimea unui bloc}<br />
type<br />
articol: array[1..LMAXA] of byte;<br />
tampon: array[1..LMAXT] of byte;<br />
var<br />
fisier: file of tampon;<br />
Zt: tampon;{ rezervarea spaţiului pentru zona tampon}<br />
it, odt: integer;{ indicatorul articolului curent în tampon respectiv numărul de octeţi<br />
disponibil în tampon}<br />
procedure Put( Za: articol; la integer);<br />
var i:integer;<br />
begin<br />
if odt
- 70 -<br />
if eof(f) then goto 9999; { sfârşit de fişier}<br />
read( fisier, Zt); it:=LAT; odt:= Scoateantett( Zt)- LAT<br />
end;<br />
la:= Scoateanteta( Zt, it)- LAA;<br />
for i:=1 to la do Za[i]:=Zt[it+LAA+i];{ mută din tampon în articol}<br />
it:= it+LAA+la; odt:=odt-LAA-la;<br />
goto 9998; { se întoarce un articol efectiv}<br />
9999:<br />
la:=-1; { se întoarce”sfârşit de fişier”}<br />
9998:<br />
end; { Get}<br />
Dacă în urma apelului procedurii Get utilizatorul primeşte ca lungime de articol citit<br />
valoarea -1 înseamnă că s-a ajuns la sfârşitul fişierului.<br />
Se impun trei observaţii privind închiderea şi deschiderea unui fişier:<br />
- dacă fişierul e deschis pentru citire( se va folosi numai procedura Get) atunci SGF<br />
atribuie în momentul deschiderii odt:=0 astfel că la primul apel al procedurii Get se va face<br />
citirea fizică a primului bloc din fişier.<br />
- dacă fişierul e deschis pentru scriere( se va folosi numai procedura Put) atunci SGF<br />
atribuie în momentul deschiderii it:= LAT; odt:=LMAXT-LAT; realizându-se începutul<br />
introducerii de articole de la un tampon vid. În plus, cele două atribuiri fac tamponul disponibil,<br />
ocolind scrierea tamponului deja existent, acţiune fără sens la prima scriere în fişier<br />
- utilizatorul trebuie să ceară SGF închiderea fişierului la terminarea lucrului cu acesta(<br />
obligatoriu dacă fişierul a fost deschis pentru scriere). La închiderea unui fişier deschis pentru<br />
scriere, SGF execută Puneantett( Zt, LAT+it-1); write( fisier, Zt). Dacă se omite comanda de<br />
închidere a fişierului, conţinutul ultimului buffer nu va mai fi scris în fişier.<br />
În ceea ce priveşte accesul direct şi alte operaţii( în afară de citiri şi scrieri), tehnica<br />
blocării şi deblocării este aplicabilă. Pentru a putea realiza operaţiile de midificare, ştergere,<br />
adăugare, SGF gestionează zona tampon astfel:<br />
- câtă vreme s-a acţionat numai asupra articolelor aflate în acelaşi tampon, acesta e<br />
păstrat ca tampon curent<br />
- când se impune schimbarea tamponului curent, SGF ştie dacă acesta a fost modificat<br />
sau nu şi îl depune pe suport înainte de a fi înlociut, dacă este cazul.<br />
2.3.3. Acţiunile SGF la nivel de fişier<br />
În această secţiune ne vom ocupa de acţiunile SGF ce privesc fişierul ca o entitate şi ne<br />
vom ocupa de fişiere memorate pe disc.<br />
Operaţiile care se vor studia sunt cele de deschidere şi închidere a unui fişier, de creare,<br />
de ştergere, de copiere, de schimbare a numelui sau de listare( dacă este text) a unui fişier. Înainte<br />
de a detalia aceste operaţii se vor prezenta structurile de date pe care trebuie să le întreţină SGF<br />
pentru a putea realiza operaţiile.<br />
Descriptorul de fişier. Informaţiile de descriere a unui fişier sunt conţinute într-un<br />
articol special numit descriptor de fişier. Locul de memorare a articolului descriptor este într-un<br />
loc special numit directorul de fişier( despre care se va vorbi în secţiunea următoare). Într-un<br />
descriptor de fişier apar patru grupe de informaţii: identificarea fişierului, informaţii privind<br />
adresele fizice disc pe care le ocupă, informaţii de control al accesului la fişier, informaţii de<br />
organizare şi calendaristice.<br />
Identificarea fişierului. Această informaţie este compusă dintr-o pereche (N, I). Valoarea<br />
N conţine numele simbolic al fişierului şi este un şir de caractere cu structura prezentată anterior;<br />
prin această valoare SGF realizează lagătura cu utilizatorul. Valoarea I este un număr prin care<br />
descriptorul este reperat pe disc în mod direct; prin această valoare SGF realizează legătura cu
- 71 -<br />
celelalte componente ale SO. Diverse SO folosesc pentru I diferite denumiri: i-node( UNIX),<br />
handle( MS_DOS), pointer în INDEXF.SYS( RSX) etc. Identificatorul de fişier este folosit de<br />
către diferite programe utilitare pentru refacerea unei structuri de fişiere compromise.<br />
Adresele fizice ocupate de fişier. De regulă un fişier ocupă pe disc mai multe zone; în<br />
funcţie de tehnica de alocare folosită, în aceste adrese se vor memora informaţiile necesare<br />
regăsirii articolelor fişierului.<br />
Controlul accesului la fişier. Conţine informaţii despre cine are drepturi de acces la fişier<br />
şi ce fel de drepturi are şi informaţii privind reglementarea multiaccesului simultan la fişier(<br />
pentru SO multiutilizator).<br />
Informaţii de organizare şi calendaristice. Aici se trec mai multe tipuri de informaţii<br />
printre care:<br />
- modul de organizare a fişierului: secvenţial, secvenţial-indexat, înlănţuit,...<br />
- formatul articolelor: fix, variabil, fişier text şi standardul de codificare( ASCII,<br />
EBCIDIC);<br />
- data şi ora creării( ultimei actualizări, ultimea citiri);<br />
- numărul total de consultări ale fişierului;<br />
- dispoziţii de păstrare a fişierului: permanent, temporar, un număr de zile etc.<br />
Funcţiile de deschidere şi închidere( open şi close). Acţiunile SGF desfăşurate înaintea<br />
primului acces la un fişier sunt grupate în operaţia de deschidere( Open) a fişierului. Acţiunile<br />
SGF desfăşurate după ultimul acces la un fişier sunt grupate în operaţia de închidere ( Close) a<br />
fişierului respectiv.<br />
Rutina de deschidere Open. Operaţia Open informează SO că un anumit fişier va deveni<br />
activ. Prima sarcină a deschiderii este de a face legătura între informaţiile de identificare a<br />
fişierului şi variabila din program care prin care utilizatorul se referă la fişier. Prin deschidere<br />
sunt efectuate controale asupra drepturilor de acces ale utilizatorului la fişier, se fac iniţializari<br />
necesare acceselor ulterioare etc. Concret, în funcţie de condiţiile de deschidere avem:<br />
a) pentru un fişier care există deja pe disc:<br />
- realizează legătura între variabila de program ce indică fişierul, suportul pe care se află<br />
fişierul şi descriptorul de fişier aflat pe disc<br />
- verifică pe baza drepturilor de acces dacă utilizatorul are sau nu acces la fişier.<br />
b) pentru un fişier nou, ce urmează a fi creat:<br />
- alocă spaţiu pe disc pentru memorarea viitoarelor articole ale fişierului<br />
c) atât la fişier nou cât şi la cel existent:<br />
- alocă memorie internă pentru zonele tampon necesare accesului la fişier;<br />
- încarcă rutinele de acces la articolele fişierului şi execută instrucţiunile lor de<br />
iniţializare;<br />
- generează o formă cadru a instrucţiunilor de comandă a canalului I-O;<br />
- memorează unele dintre datele obţinute la a), b), c) şi cele din descriptorul fişierului<br />
într-o structură de date din memoria internă, cunoscută sub numele de bloc de control( File<br />
Control Bloc, FCB); fiecare utilizator are pentru fiecare fişier propriul FCB, unele fişiere(<br />
standard) au FCB în monitorul sistemului.<br />
Rutina de închidere Close. Operaţia de închidere anunţă SO că fişierul încetează a mai fi<br />
activ. Unele SO cer anunţarea explicită a închiderii, altele efectuează automat închiderea<br />
fişierului la sfârşitul programului. Prin închidere se pun la zi informaţiile generale despre fişier(<br />
lungime, adrese de început şi de sfârşit, data modificării etc).<br />
În funcţie de condiţiile de închidere avem:<br />
a) pentru fişiere temporare create în programul curent şi de care nu mai este nevoie:<br />
- se şterge fişierul şi se eliberează spaţiul disc ocupat.<br />
b) pentru fişiere nou create care trebuie reţinute:<br />
- creează o nouă intrare în directorul discului.<br />
c) pentru toate fişierele care trebuie reţinute:
- 72 -<br />
- inserează dacă e cazul marcajul EOF după ultimul articol al fişierului;<br />
- goleşte( pune pe suport) ultimele informaţii existente în zonele tampon;<br />
- pune la zi cele patru grupe de informaţii din descriptorul de fişier cu valorile curente;<br />
- dacă fişierul a fost modificat se marchează acest lucru şi se pune numele fişierului întro<br />
listă a sistemului( în vederea salvării de către SO a tuturor fişierelor modificate).<br />
d) pentru toate fişierele, permanente sau temporare:<br />
- aduce capul de citire a discului în poziţia zero;<br />
- eliberează spaţiul de memorie ocupat de către FCB;<br />
- eliberează spaţiile ocupate de zonele tampon în memoria operativă.<br />
Alte operaţii globale cu fişiere. Operaţiile ce urmează se execută de regulă prin<br />
intermediul unor programe utilitare ale SO, în particular prin intermediul unor comenzi standard<br />
ale SO.<br />
Crearea unui fişier. Pentru un fişier cu organizare simplă această operaţie coincide cu<br />
deschiderea fişierului pentru scriere. Pentru fişierele cu structură mai sofisticată crearea înseamnă<br />
o formatare care pregăteşte spaţiul fizic în vederea încărcării lui cu informaţii.<br />
Stergerea unui fişier. Această acţiune are ca efect eliberarea spaţiului fizic ocupat de<br />
articolele fişierului şi se elimină din director intrarea ce conţine descriptorul fişierului respectiv.<br />
Copierea unui fişier în alt fişier. Prin această operaţie se realizează o copiere fizică a<br />
fişierului sursă într-un fişier numit destinaţie; în urma copierii fişierele vor avea acelaşi conţinut.<br />
Schimbarea numelui de fişier. Această operaţie lasă neschimbat conţinutul fişierului, îi<br />
schimbă doar numele. Dacă se schimbă numele sau tipul fişierului operaţia se numeşte<br />
redenumire, dacă se schimbă calea de acces spre fişier operaţia poartă numele de mutare.<br />
Listarea fişierului. Operaţia este un caz particular al copierii, atunci când fişierul sursă<br />
este de tip text, iar fişierul destinaţie este imprimanta sau ecranul unui terminal.<br />
Concatenarea mai multor fişiere. Această operaţie este o generalizare a copierii.<br />
Concatenarea se poate face în două moduri: adăugarea unor fişiere sursă la un fişier existent,<br />
obţinându-se un fişier nou sau crearea unui fişier nou ce conţine fişierele sursă alipite.<br />
Diverse SO mai conţin şi alte programe utilitare ce operează cu fişierele ca entităţi. Iată<br />
câteva dintre aceste operaţii:<br />
Compararea a două fişiere. Compararea se face parcurgând secvenţial cele două fişiere,<br />
octet cu octet; după depistarea unui număr fixat de nepotriviri compararea se opreşte cu rezultat<br />
fals. Dacă cele două fişiere nu au aceeaşi lungime sau nu sunt de acelaşi tip, compararea nu se<br />
lansează.<br />
Fuzionarea a două sau mai multe fişiere. Pentru a se realiza această operaţie se<br />
stabileşte un criteriu de stabilire a ordinii de fuzionare a articolelor din fişiere; de obicei articolele<br />
au un atribut comun şi apar în fişiere ordonate după valorile atributului respectiv.<br />
Sortarea articolelor unui fişier. Este o operaţie des utilizată în special în prelucrările cu<br />
caracter economic. Unele limbaje de programare dispun chiar de instrucţiuni special în acest sens(<br />
de exemplu Cobol).<br />
Operaţii de filtrare a unui fişier. Prin filtru se înţelege un program care citeşte un fişier<br />
şi creează din el altul pe baza unor criterii( sortare, eliminarea liniilor cu un anumit conţinut,<br />
macroprocesarea etc).<br />
Compactarea unuia sau mai multor fişiere în vederea arhivării lor. Se foloseşte pentru<br />
păstrarea în arhive a unor fişiere al căror conţinut va fi util doar peste un anumit interval de timp<br />
sau pentru a păstra copii de siguranţă a unor fişiere importante. Compactarea poate fi văzută ca o<br />
codificare a datelor în care codurile caracterelor au lungimi variabile: caracterele întâlnite mai<br />
frecvent sunt reprezentate printr-un număr mai mic de cifre binare; aceste tipuri de coduri fac<br />
parte din clasa codurilor Huffman. Prin compactare se realizează o economie a spaţiului fizic.<br />
Pentru fiecare program de compactare există şi program de compactare care reface structura<br />
fişierului plecând de la arhivă.
- 73 -<br />
Protecţia, securitatea şi controlul accesului. Motivele pentru care protecţia şi securitatea<br />
datelor sunt un aspect captivant al ştiinţei calculatoarelor sunt următoarelor:<br />
- importanţa protecţiei informaţiilor faţă de accesul neautorizat la ele;<br />
- “secretul” în care fabricanţii de SC şi soft ţin detaliile legate de realizarea protecţiei;<br />
- spectaculoasele furturi realizate cu ajutorul calculatorului;<br />
- apatiţia viruşilor calculatoarelor.<br />
Protectia informaţiei poat efi privită din două puncte de vedere:<br />
- aspectul tehnic: problemele de protecţie şi securitate sunt rezolvate în primă instanţă de<br />
echipamentul hard după care sunt realizate soft( SO deţine mecanisme prin care permite<br />
utilizatorilor să-şi realizeze propriile mecanisme de protecţie.<br />
- aspectul economic: decide cât de complex( şi scump) terbuie să fie un mecanism de<br />
protecţie având în vedere pagubele ce se pot produce prin încălcarea protecţiei şi securităţii.<br />
Utilizarea de parole, fişiere ascunse, activarea unor programe preliminare înainte de a<br />
folosi efectiv un produs sunt numai câteva mijloace( simple) de protecţie.<br />
Pentru a realiza protecţia, securitatea şi controlul accesului la fişiere din perspectiva SO<br />
se poate folosi o matrice A de control al accesului în care A(i,j)=1 dacă utilizatorul i are drept de<br />
acces la fişierul j şi 0 în caz contrar, numărul liniilor matricii este egal cu numărul utilizatorilor,<br />
iar numărul coloanelor este egal cu numărul fişierelor de pe disc. Prin această tehnică se ocupă un<br />
spaţiu de memorie mare( deşi matricea A este matrice rară) şi deci se foloseşte mai rar. O altă<br />
tehnică ar fi cea a împărţirii utilizatorilor în clase cum ar fi:<br />
- proprietar: de regulă cel care creează fişierul; stabileşte pentru toţi ceilalţi utilizatori<br />
drepturile de acces<br />
- utilizator specificat: este nominalizat de către proprietar şi are statut special în raport cu<br />
fişierul<br />
- grup sau proiect: grup de utilizatori ce lucrează împreună la acelaşi proiect şi utilizează<br />
în comun un anumit fişier<br />
- public: restul utilizatorilor.<br />
Se va exemplifica în continuare cum se poate realiza protecţia sub diferite SO.<br />
UNIX. În acest SO utilizatorii sunt împărţiţi în patru clase:<br />
- u( User) defineşte proprietarul fişierului;<br />
- g( Group) defineşte un grup de utilizatori;<br />
- o( Other) reuneşte utilizatorii din sistem care nu au fost prinşi în primele două clase.<br />
În momentul primului contact cu SO UNIX utilizatorul ia legătura cu administratorul<br />
sistemului care dă utilizatorului o parolă şi îl integrează într-un grup, în funcţie de interesele<br />
utilizatorului. Fiecare clasă de utilizatori are la dispoziţie trei atribute independente, fiecare<br />
putând fi permis sau interzis:<br />
- r permite sau interzice citirea din fişier<br />
- w permite sau interzice scrierea, adăugarea, modificarea sau ştergerea de octeţi din fişier<br />
- x indică dreptul de a executa fişierul respectiv( care conţine instrucţiuni maşină sau este<br />
fişier de comenzi).<br />
În mod implicit atributele sunt stabilite de componenta ce creează fişierul( un fişier<br />
executabil va primi atributul x). Proprietarul şi administratorul sunt singurii care pot modifica<br />
protecţia fişierului prin comanda chmod.<br />
MS-DOS. Fişierele DOS au şase perechi de atribute, dintre care două se referă la<br />
protecţie în mod direct, iar celelalte indirect. Cele şase perechi sunt:<br />
- R+ fişier protejat la scriere;<br />
- R- este permisă şi scrierea şi citirea fişierului<br />
- HID+ fişier ascuns<br />
- HID- fişier vizibil
- 74 -<br />
- SYS+ fişier al sistemului<br />
- SYS- fişier utilizator obişnuit<br />
- V+ descriptorul nu se referă la un fişier obişnuit ci la eticheta volumului respectiv<br />
- V- descriptor obişnuit, nu etichetă de volum<br />
- S+ descriptorul respectiv indică un fişier director<br />
- S- descriptorul unui fişier obişnuit<br />
- A+ fişier destinat arhivării deoarece conţinutul său a fost modificat<br />
- A- de la ultima restaurare a fişierului s-au făcut eventual numai citiri, deci nu mai trebuie<br />
salvat.<br />
Atributele pot fi modificate cu comanda ATTRIB sau folosind programul Norton<br />
Utilities. Atributul V+ este fixat la formatarea discului, iar S+ la crearea unui nou director.<br />
Informaţiile asupra atributelor de fişier sunt memorate în descriptorul de fişier. Primii şase biţi<br />
indică în ordine atributele R, HID, SYS, V, S, A şi au valoarea 1 dacă atributul e cu semnul + şi 0<br />
dacă e cu -.<br />
2.3.4. Moduri de organizare a fişierelor<br />
Organizarea unui fişier este modalitatea în care sunt aranjate articolele sau părţi din ele<br />
astfel încât să permită modurile de acces dorite. Ne vom limita în continuare numai la fişierele<br />
clasice şi pentru simplitate presupunem că toate articolele fişierului sunt de acelaşi tip şi sunt<br />
împărţite în câmpuri( atribute).<br />
Organizarea secvenţială. Se foloseşte mult datorită simplităţii ei.. Între articolele unui<br />
astfel de fişier există o relaţie de ordine astfel: articolul X urmează în fişier unui articol Y dacă X<br />
a fost introdus în fişier după introducerea lui Y. Acest mod de organizare este natural pentru<br />
suportul bandă; el există şi pentru suportul disc, dar aici două articole vecine pentru utilizator nu<br />
sunt neapărat vecine şi fizic. Formatul articolelor unui fişier secvenţial poate fi fix sau variabil.<br />
Accesul la un articol al unui fişier secvenţial se face secvenţial.<br />
Fişiere în acces direct prin poziţie. Un astfel de fişier are de regulă articole cu format<br />
fix. Prin SGF există posibilitatea de a avea acces în mod direct la orice sector disc alocat fişierului<br />
respectiv. Să presupunem( ca în figura următoare) că sectoarele ocupate de fişier sunt<br />
numerotate 0, 1, 2,..., n. Capacitatea unui sector se va nota cu s, iar lungimea unui articol<br />
presupunem că este l( nu se vor lua în considerare antetele de bloc şi de articol). Se presupune că<br />
articolele sunt plasate pe suport succesiv chiar dacă un articol începe pe un sector şi se termină pe<br />
altul.<br />
Sector<br />
0 1 2 3 . . . n-1<br />
s<br />
Fie Articol r numărul articolului<br />
0 1<br />
solicitat. 2 3<br />
Cu<br />
4<br />
sr<br />
5<br />
se notează ... a-1 numărul sectoarului în care începe<br />
articolul solicitat, iar cu or numărul<br />
l<br />
octetului în cadrul sectorului. Pentru a localiza în acces direct<br />
acest articol, SGF face următoarele calcule: sr: ( rl) div s; or: ( r<br />
l)mod s;<br />
După aceste calcule, SGF face acces direct la sectorul sr şi începând cu octetul or extrage<br />
sau depune articolul solicitat.<br />
În cazul articolelor cu format variabil această schemă nu funcţionează. Există alte tehnici<br />
pentru acces în acest caz, de regulă se reţine fie lista adreselor disc la care începe fiecare articol,<br />
fie lista lungimilor acestor articole sau, în cazul în care lungimile articolelor nu diferă prea mult,<br />
se reţine pentru fiecare articol cu cât este mai lung decât articolul de lungime minimă( aceste<br />
valori se pot reţine pe un număr mai mic de biţi, de exemplu dacă diferenţele sunt mai mici de 15<br />
octeţi, ele se pot reţine pe 4 biţi). Majoritatea limbajelor de programare de nivel înalt au
- 75 -<br />
implementate mecanisme de acces direct prin poziţie pentru articole de format fix, de exemplu<br />
funcţia fseek pentru limbajul „C‟ standard.<br />
Fişiere inverse. Un astfel de fişier permite un mod natural de organizare pentru a se<br />
realiza accesul direct prin conţinut. Această organizare presupune existenţa în acelaşi timp a<br />
două fişiere unul de bază şi altul invers care sunt create şi actualizate simultan. Fişierul invers<br />
conţine pentru fiecare cheie specificată de utilizator adresele disc la care se află articolele ce<br />
conţin cheia respectivă.<br />
Să considerăm de exemplu următoarele chei ( NUME, “Alb”), ( NUME, “Pop”),(<br />
FUNCŢIA, “student”). Fişierele de bază şi invers pot să arate astfel:<br />
Fisier<br />
invers<br />
( NUME, “Alb”) n 1 a 11 a 12 . . . a 1n1<br />
( NUME, “Pop”) n 2 a 21 a 22 . . . a 2n2<br />
. . . . . . . .<br />
( FUNCŢIA, “student”) n p a p1 a p2 . . . a pnp<br />
Fisier<br />
de baza<br />
“Alb”<br />
“Alb”<br />
“student”<br />
“Pop”<br />
“student”<br />
Fişierul invers conţine p chei. Prin n 1 , n 2 ,..., n p se specifică câte articole din fişierul de<br />
bază conţin respectiv cheile 1, 2, ..., p. Prin a ij s-a notat adresa celui de al j-lea articol al fişierului<br />
de bază care conţine cea de-a i-a cheie indicată în fişierului invers. Este evident că are loc relaţia<br />
j k a a , i<br />
. Fiecare articol al fişierului invers are pe lângă cheie atâţia biţi câte<br />
ij<br />
ik<br />
articole are fişierul de bază. Fiecare bit este 1 dacă articolul are cheia respectivă sau este 0 în caz<br />
contrar. Tehnica inversării prin şiruri de biţi este avantajoasă şi pentru faptul că permite regăsirea<br />
rapidă a tuturor articolelor care verifică o expresie logică de chei. Spre exemplu, dacă se cer toate<br />
articolele ce conţin simultan cheile K i şi K j , atunci între articolele i şi j din fişierul invers se<br />
execută o operaţie şI bit cu bit. Dacă se cer toate articolele care conţin cel puţin una dintre cheile<br />
K i sau K j atunci se execută o operaţie SAU bit cu bit, iar dacă se cer toate articolele ce nu conţin<br />
cheia K i atunci sunt inversaţi toţi biţii articolului i al fişierului invers.<br />
Indiferent de modul de realizare al inversării, dacă în fişierul invers sunt toate cheile din<br />
fişierul de bază, atunci în orice moment din fişierul invers se poate crea fişierul de bază şi<br />
reciproc.<br />
Fişiere multilistă. Tehnica inversării devine ineficientă în cazul fişierelor de bază foarte<br />
mari pentru că articolele fişierului invers devin lungi şi greu de manipulat. Abordarea multilistă<br />
înlătură acest inconvenient. Acest mod de organizare este conceput pentru acces direct prin<br />
conţinut.<br />
Utilizatorul defineşte o serie de atribute şi o serie de valori ale acestora care vor fi cheile<br />
fişierului; presupunem pentru simplitate că au fost selecţionate toate cheile fişierului de bază.<br />
SGF ataşează fiecărei chei dintr-un articol un pointer către articolul următor ce conţine aceeaşi<br />
cheie; articolele fişierului de bază sunt legate prin atâtea liste câte chei sunt în fişier. Fiecare<br />
articol participă la c liste, unde c este numărul de scrieri ale articolului. Se creează de asemenea o
- 76 -<br />
zonă conţinând cheile fişierului şi adresele primelor articole ce conţin cheile respective( capetele<br />
de listă), zonă numită fişier director. Iată în continuare un exemplu de fişier multilistă:<br />
Fisier<br />
de chei<br />
(NUME “Alb”) a 11<br />
(NUME “Pop”) a 21<br />
(FUNCŢIA “student”)<br />
a p1<br />
Fisier<br />
de baza<br />
a 11 a 12 a 1n1<br />
. . .<br />
a p1 a p2 a pnp<br />
. . .<br />
Ca şi la fişierele inverse şi la cele multilistă are loc relaţia j k aij<br />
aik<br />
, i<br />
şi în plus<br />
relaţia i k a a poate să apară de foarte multe ori, eficienţa organizării multilistă creşte<br />
ij<br />
kj<br />
proporţional cu apariţia acestei relaţii.<br />
Fişiere secvenţial-indexate. Acest mod de organizare este cel mai des întâlnit pentru<br />
acces direct prin conţinut. Se presupune că există pentru date un atribut cu valori unice pentru<br />
fiecare articol( atribut index). Articolele sunt scrise pe suport în acces secvenţial şi sunt plasate în<br />
ordinea crescătoare a valorilor indexului şi sunt grupate în blocuri de informaţie numite pagini.<br />
Deci toate valorile indexului dintr-o pagină sunt mai mici sau mai mari decât valorile indexului<br />
din altă pagină. În paralel cu crearea fişierului se creează o tabelă de indecşi in care se trece<br />
pentru fiecare fişier adresa disc a paginii şi valoarea celui mai mare index din pagină( dacă<br />
fişierul de indecşi este prea mare se poate organiza ca arbore).<br />
De exemplu, să considerăm un fişier secvenţial-indexat ce are o tabelă de indecşi<br />
organizată pe 1, 2 sau 3 nivele; criteriul de alegere a nivelelor este legat de structura fizică a<br />
informaţiei pe discul magnetic. Conţinutul tabelei este următorul:<br />
Nivelul 3- fişier, are atâtea intrări câte volume disc ocupă fişierul şi fiecare intrare are<br />
forma:<br />
Ultimul index din volum Numărul volumului<br />
Tabela este plasată pe ultimul volum al fişierului.<br />
Nivelul 2- volum, are atâtea intrări câţi cilindri sunt alocaţi fişierului în volumul respectiv<br />
şi are forma:<br />
Ultimul index din cilindru Numărul cilindrului<br />
Tabela este plasată pe ultimul cilindru alocat fişierului în volumul respectiv.<br />
Nivelul 1- cilindru, are atâtea intrări câte pagini din fişier există pe cilindrul respectiv şi<br />
are forma:<br />
Ultimul index din pagină Adresa paginii<br />
Tabela este plasată pe ultimele sectoare ale cilindrului.<br />
O porţiune dintr-un fişier secvenţial-indexat poate să arate astfel:<br />
Fişier:<br />
82<br />
121<br />
1<br />
Tabele de indecşi<br />
Volum:<br />
12<br />
31<br />
82<br />
2<br />
Cilindru:<br />
3<br />
7<br />
12<br />
16<br />
25
- 77 -<br />
Prin căutare binară se ajunge în mod direct la pagina ce conţine articolul căutat. În cadrul paginii<br />
căutarea se face secvenţial. Deci din cel mult trei accese la disc se obţine articolul căutat( în<br />
figură sunt numerotate accesele la disc şi informaţiile invocate pentru a obţine articolul cu cheia<br />
21). Dacă fişierul este monovolum, nivelul trei al tabelei nu mai este necesar, iar dacă fişierul<br />
ocupă cel mult un cilindru, nu mai este necesar nici nivelul doi.<br />
Apar în acest caz două dezavantaje. Primul se referă la necesitatea reorganizării<br />
frecvente; pentru a se elimina acest neajuns au apărut fişierele ce utilizează structurile de B-<br />
arbori. Al doilea dezavantaj este legat de necesitatea de a efectua mai multe accese la disc pentru<br />
un articol; pentru a elimina acest dezavantaj au apărut fişierele selective.<br />
Actualizarea unui fişier secvenţial-indexat se face în acces direct. Dacă de exemplu se<br />
doreşte inserarea unui articol având valoarea indexului 20 se observă ca locul lui ar fi în pagina<br />
cu indecşii 17,19,21 şi 25( această pagină se numeşte parte principală). Dar pentru aceasta ar<br />
trebui reorganizată tabela de indecşi şi ar trebui ca toate articolele cu index mai mare ca 20 să fie<br />
deplasate şi această soluţie nu convine. Soluţia este de a lega articolele între ele printr-o listă<br />
simplu înlănţuită şi memorarea articolului de inserat într-o zonă numită parte de depăşire. În<br />
exemplul prezentat, articolul cu indexul 19 are un pointer spre partea de depăşire spre articolul cu<br />
index 20, iar acesta are pointer spre partea principală spre articolul cu indexul 21. Dacă se fac<br />
multe inserări între chei din partea principală, atunci lista leagă multe articole în partea de<br />
depăşire, iar randamentul accesului la disc scade. În cazul ştergerii, fie rămâne un loc nefolosit în<br />
partea principală, fie trebuie reorganizată o listă în partea de depăşire, deci trebuie făcută frecvent<br />
reorganizarea fişierului ceea ce scade randamentul global al fişierului.<br />
Fişiere selective. Aceste fişiere sunt o replică a celor secvenţial-indexate în următorul<br />
sens: În timp ce fişierele secvenţial-indexate au funcţia de regăsire materializată în tabele de<br />
indecşi, cele selective materializează funcţia de regăsire printr-un calcul efectuat de către CPU,<br />
eliminându-se astfel accesele la disc pentru căutare în tabele. Definirea funcţiei de regăsire este<br />
însă puternic dependentă de datele din fişier. Organizarea selectivă este folosită tot pentru accesul<br />
direct prin conţinut. În acest caz se presupune că datele ce se vor înregistra permit existenţa unui<br />
index. Se poate defini o funcţie f :{ valori _ posibile _ index } { 01 , ,..., n 1 } numită funcţie<br />
de randomizare sau funcţie hash şi care este definită de către utilizator. Numărul n reprezintă
- 78 -<br />
numărul claselor în care se împart articolele fişierului, iar articolele pentru care se obţine aceeaşi<br />
valoare a funcţiei de randomizare se spune că sunt articole sinonime( numărul de articole<br />
sinonime este bine să fie apropiat de numărul de articole ce încap într-un bloc de informaţie).<br />
Scrierea într-un fişier selectiv se face astfel: se aplică funcţia de randomizare valorii<br />
indexului şi se obţine clasa din care face parte articolul. Partea principală a fişierului este formată<br />
din câte o pagină pentru fiecare clasă. Dacă pagina nu este plină atunci se depune articolul în<br />
pagina respectivă, iar dacă este plină se pune în partea de depăşire şi se leagă printr-o listă<br />
înlănţuită cu ultimul articol sinonom cu el din partea principală. La citire, utilizatorul furnizează<br />
indexul articolului, iar SGF determină clasa din care acesta face parte şi în cadrul clasei căutarea<br />
se face secvenţial.<br />
Dezavantajul acestui tip de organizare este că pot exista clase foarte aglomerate şi deci cu<br />
zone de depăşire mari, acest lucru depinzând de datele din fişier.<br />
Fişiere organizate folosind B-arbori. Această tehnică este foarte utilizată şi are multe<br />
variante. Folosirea ei se datorează faptului că de obicei tabelele de indecşi sunt prea mari pentru a<br />
încăpea în memoria internă, iar tehnica ce foloseşte B-arbori reduce numărul de accese la disc.<br />
B-arbore regular. Organizarea unui astfel de B-arbore este următoarea: fiecare nod este<br />
prevăzut cu m locuri în care pot fi memorate m chei( aceste chei sunt valorile ale unui index al<br />
fişierului). În fiecare nod pot fi maximum m chei şi minimum m/2 chei care apar în ordine<br />
crescătoare. Odată cu cheile se memorează şi adresele corespunzătoare din fişierul de bază.<br />
Înaintea primei chei, după ultima cheie şi între două chei din nod se află pointeri spre noduri<br />
subordonate, primul pointer indicând subarborele în care se află toate cheile mai mici decât prima<br />
cheie, ultimul pointer indicând subaborele în care se află toate cheile mai mari decât ultima cheie<br />
din nod, iar pointerul dintre două chei indicând subarborele ce conţine toate cheile cu valori<br />
cuprinse între cele două chei din nod.<br />
Un exemplu de arbore cu m=2 este următorul:<br />
20<br />
8<br />
30 65<br />
5<br />
5<br />
15 21 41<br />
2 2 2 2 2 2<br />
78<br />
2<br />
2 7 16 20 22 29 35 37 42 50 67 77 80 91<br />
Căutarea într-un B-arbore este o căutare binară obişnuită: se depistează într-un nod al<br />
arborelui fie cheia căutată fie subarborele în acre ar trebui să se afle.<br />
Inserarea se face astfel încât arborele să rămână echilibrat( pe toate ramurile există<br />
acelaşi număr de nivele). Dacă un nod este prea plin( ar trebui să conţină m+1 chei), B-arborele<br />
se autoconfigurează: se încearcă o migrare de chei între două noduri vecine trecând prin părintele<br />
lor pentru a încărca aproximativ doi vecini. În ultimă instanţă un nod prea plin se desparte în două<br />
noduri cel puţin jumătate pline.<br />
ştergerea păstrează calitatea de B-arbore: când un nod este prea gol( are numai m/2-1<br />
chei) se încearcă o migrare de chei între două noduri vecine; din doi vecini, unul jumătate plin, iar
- 79 -<br />
altul mai puţin de jumătate plin, se formează un singur nod. În figura următoare este reprezentat<br />
arborele exemplificat, dacă s-a inserat cheia cu valoarea 36, după care s-a şters cheia cu valoarea<br />
65:<br />
20<br />
8<br />
30 65<br />
6<br />
4<br />
15 21 36 41<br />
78<br />
2 2 2 1<br />
1 2<br />
1<br />
2<br />
2 7 16 20 22 29 35 37 42 50 77 80 91<br />
36 65<br />
Dezvoltarea unui B-arbore se face mai mult în lăţime decât în înălţime. Dacă un B-arbore<br />
N 1<br />
conţine N chei, atunci numărul maxim de nivele este 1<br />
log<br />
[ m/ 2]<br />
( ). Această calitate<br />
2<br />
asigură un număr minim de accese la disc pentru găsirea unei chei. Un fişier organizat ca B-<br />
arbore este superior unuia secvenţial-indexat din următoarele motive:<br />
- cheile pot fi furnizate în orice ordine, nu neapărat crescătoare<br />
- dispare zona de depăşire<br />
- căutarea se face strict în acces direct, eliminându-se căutarea secvenţială în cadrul unei<br />
pagini.<br />
Un dezavantaj important al acestei organizări este că nu permite accesul secvenţial în<br />
ordinea crescătoare a cheilor. Pentru a înlătura acest neajuns au apărut variante ce permit şi<br />
accesul secvenţial, unul dintre acestea fiind B + -arborele.<br />
Principala deosebire dintre B-arbore şi B + -arbore este aceea că ultimul conţine chei şi<br />
pointeri la fişierul de bază numei în nodurile terminale ale arborelui, nodurile interioareorganizate<br />
ca B-arbore - au doar rolul de a indică nodul terminal ce conţine cheia căutată;<br />
nodurile terminale sunt legate între ele printr-o listă înlănţuită, permiţându-se accesul secvenţial.<br />
2.3.5. Acţiunile SGF la nivel de suport disc<br />
La acest nivel SGF are trei sarcini principale: implementarea unui sistem adecvat de<br />
regăsire a fişierelor aflate pe volumul de disc respectiv, ţinerea evidenţei spaţiului neutilizat pe<br />
disc şi punerea la dispoziţia componentelor de creare sau extindere fişiere a acestui spaţiu<br />
disponibil.<br />
Sisteme de cataloage( directori). Fiecare volum disc trebuie să conţină o tabelă cu<br />
fişierele existenete pe disc şi cu informaţiile necesare accesului la aceste fişiere; o astfel de tabelă<br />
se numeşte catalog sau director. Fiecare intrare a unui director conţine un descriptor de fişier.<br />
Operaţii asupra directorilor. În esenţă, asupra directorilor se fac următoarele operaţii:
- 80 -<br />
Căutare: o structură de directori conţine câte o intrare pentru fiecare fişier, în care se află<br />
descriptorul de fişier sau pointer la el. Operaţia trebuie să permită identificarea unui fişier sau a<br />
unui grup de fişiere.<br />
Inserare: la crearea unui nou fişier în sistemul de directori se va introduce o nouă intrare<br />
ce conţine descriptorul fişierului respectiv.<br />
ştergere: la ştergerea unui fişier se şterg din directori informaţiile referitoare la fişierul<br />
respectiv.<br />
Listarea unui director: fiecare SO dispune de programe ce afişează conţinutul directorilor<br />
şi valorile din directori pentru fiecare fişier în parte( comanda DIR sau ls sub UNIX).<br />
Salvare- restaurare: operaţia de salvare, de obicei pe bandă a conţinutului unui disc se<br />
face pentru a preveni accidentele sau pentru a permite altor fişiere să ocupe spaţiul; odată cu<br />
salvarea fişierelor se salvează şi directorii, iar la restaurare sunt efectuate operaţiile inverse.<br />
În ceea ce priveşte structura logică a unui sistem de directori, există patru tipuri de<br />
structuri:<br />
- directori cu un singur nivel<br />
- directori cu două nivele<br />
- directori cu structură de arbore<br />
- directori cu structură de graf aciclic.<br />
Directori cu un singur nivel. Aceasta este cea mai simplă structură de directori: toate<br />
fişierele de pe disc sunt repertorizate în acelaşi director. În acest caz există o serie de restricţii<br />
asupra numelor fişierelor şi a numărului lor. SO ce foloseşte acest tip de structură de directoare<br />
este SO CP/M; el conţine pe pista 2 a fiecărei dischete tabela de fişiere.<br />
Directori cu două nivele. O astfel de organizare elimină neajunsul unicităţii numelui de<br />
fişier( care apare în cazul precedent). În acest caz există la nivelul superior directorul Master(<br />
MFD- Master File Directory) şi acesta conţine câte o intrare pentru fiecare utilizator al sistemului,<br />
intrare care punctează spre un director utilizator( UFD- User File Directory). Din fiecare UFD se<br />
punctează spre fişierele utilizatorului respectiv. SO ce utilizează acest tip de structură este SO<br />
RSX. O astfel de structură este prezentată în figura următoare:<br />
MFD UFD 1 UFD 2 UFD 3 UFD 4<br />
UFD<br />
1:<br />
A<br />
TES<br />
T<br />
DAT<br />
A<br />
UFD 2:<br />
B: UFD A: DATA: X:<br />
4:<br />
A:<br />
B: A:<br />
X:<br />
DATA:<br />
TEST<br />
DATA:<br />
:<br />
Directori cu structură de arbore. SO cel mai cunoscut ce utilizează acest tip de<br />
structură este UNIX. De asemenea, SO MS_DOS utilizează începând cu versiunea 2 astfel de<br />
directori. Pentru o prezentare unitară, se va studia sistemul de fişiere UNIX. Sub UNIX există trei<br />
tipuri de fişiere: obişnuite, speciale şi directori.<br />
Fişierele obişnuite sunt privite ca şiruri de octeţi, accesul la un octet putându-se face fie<br />
secvenţial, fie direct prin numărul de ordine al octetului.<br />
Fişierele speciale. UNIX vede fiecare dispozitiv de I/O ca şi un fişier de tip special. Din<br />
punctul de vedere al utilizatorului nu există nici o deosebire între lucrul cu un fişier disc normal şi<br />
lucrul cu un fişier special. Avantajele pe care le are similitudinea dintre fişiere şi dispozitive sunt:<br />
- simplitatea şi eleganţa comenzilor<br />
- numele unui dispozitiv poate fi transmis ca argument în locul unuia de fişier
- 81 -<br />
- fişierele speciale au acelaşi mecanism de protecţie ca şi celelalte fişiere.<br />
Fişierele director se deosebesc de cele obişnuite prin informaţia conţinută în ele. Un<br />
fişier director conţine lista de nume şi adrese pentru fişierele subordonate lui. Uzual fiecare<br />
utilizator are un director propriu care punctează la fişierele lui obişnuite sau la alţi subdirectori<br />
definiţi de el. O intrare într-un director are forma:<br />
Numele fişierului subordonat Descriptorul fişierului( pointer spre el)<br />
În plus, fiecare director mai are două intrări speciale:<br />
- “.” care punctează spre directorul respectiv<br />
- “..” care punctează spre directorul părinte.<br />
Fiecare volum de disc conţine un director principal numit ROOT( director rădăcină). Un exemplu<br />
de astfel de structură este următoarea( cercurile reprezintă fişiere, iar dreptunghiurile directori):<br />
ROOT:<br />
A B C . ..<br />
A:<br />
D . .. G<br />
D E F . ..<br />
C:<br />
D<br />
:<br />
G . ..<br />
E:<br />
F:<br />
Fiecare utilizator foloseşte un director curent, ataşat utilizatorului la intrarea în sistem. Cu<br />
ajutorul unor programe utilitare, utilizatorul poate să-şi schimbe directorul curent(cd), unele<br />
drepturi de acces( chmod), să-şi creeze un nou director( mkdir), să şteargă un director( rmdir), să<br />
afişeze calea de acces la un director sau fişier etc. Specificarea de către utilizator a unei căi se<br />
face astfel: [/] director 1 /director 2 /.../director n /nume. Dacă este prezent primul “/” atunci<br />
specificarea căii începe din rădăcină, altfel din directorul curent.<br />
La SO MS_DOS, sistemul de directori este aproape identic doar că în specificarea căii se<br />
foloseşte “\” în loc de “/”.<br />
Directori cu structură de graf aciclic. Acest tip de structură înlătură restricţia de la<br />
structura de arbore ca un fişier sau director să poată fi accesibil dintr-un singur părinte. În<br />
anumite situaţii este utilă partajarea unei structuri de fişiere între mai mulţi utilizatori. SO UNIX<br />
permite o astfel de partajare, dar numai pentru fişierele obişnuite. De exemplu, în figura<br />
anterioară, dacă se adaugă legătura punctată, atunci fişierul “G” poate fi partajat şi căile de<br />
recunoaştere a lui sunt /A/G şi /B/D/G.<br />
Evidenţa spaţiului liber disc. În cele mai multe cazuri se păstrează multe fişiere pe<br />
acelaşi disc. Problema care se pune este de a aloca spaţiul pentru fişiere astfel încât spaţiul pe disc<br />
să fie utilizat cât mai eficient, iar informaţiile din fişiere să poată fi introduse/obţinute rapid.<br />
Pentru a exemplifica metodele de evidenţă a spaţiului liber şi pe cele de alocare, se va considera<br />
un disc ce dispune de 32 blocuri( înţelegem prin bloc unitatea de alocare a spaţiului disc),<br />
numerotate 1,2, ..., 31. În figura următoare este dată structura unui astfel de disc cu directorul<br />
memorat în blocul 0 şi care conţine 5 fişiere.<br />
G<br />
:<br />
DIRECTOR:<br />
00<br />
04<br />
08<br />
01 02<br />
05 06<br />
09 10<br />
03<br />
07<br />
11<br />
Fişier Început Lungime<br />
A 02 02
- 82 -<br />
Dintre metodele de evidenţă a spaţiului liber cele mai cunoscute sunt cele bazate pe<br />
fişiere inverse şi cele bazate pe liste înlănţuite.<br />
a) Evidenţa spaţiului prin fişier invers. În directorul volumului există o zonă rezervată<br />
pentru ocuparea volumului, zona TOV. În TOV este alocat câte un bit pentru fiecare bloc de pe<br />
disc. Dacă blocul este liber atunci bitul este zero, dacă este ocupat bitul este 1. Pentru discul din<br />
figura anterioară TOV este 1011 0011 0000 0011 1001 1111 1000 1111<br />
La alocarea unui fişier se caută şi se ocupă atâtea blocuri câte sunt necesare fişierului, după care<br />
biţii corespunzători primesc valoarea 1. La ştergerea fişierului biţii corespunzători se pun pe zero.<br />
b) Evidenţa prin listă înlănţuită. În directorul volumului există un pointer către primul<br />
sector liber, acest sector conţine un pointer la următorul sector liber ş.a.m.d. Ultimul sector are<br />
pointer de valoarea zero. Ordinea apariţiei blocurilor libere în listă este dată de cererea şi<br />
eliberarea blocurilor până la momentul respectiv. Astfel, dacă se cere ocuparea a p blocuri, se vor<br />
ocupa primele p poziţii din listă, după care blocul al p+1- lea din listă va fi primul bloc liber.<br />
Această schemă nu este foarte eficientă pentru că pentru ocuparea unor sectoare este necesar un<br />
consum mare de timp pentru operaţiile I/O care caută spaţiu liber.<br />
c) Evidenţa înlănţuită şi indexată. Pentru a descrie această metodă să presupunem că întrun<br />
bloc pot fi înregistrate n adrese de blocuri disc. În primul bloc liber, indicat din director, se<br />
memorează adresele a n blocuri libere. Primele n-1 sunt adrese de sectoare efectiv libere, iar<br />
ultima adresă punctează la un alt bloc liber care conţine şi el adresele a n blocuri libere ş.a.m.d. În<br />
acest mod numărul operaţiilor I/O necesare pntru căutarea de spaţiu liber se micşorează în medie<br />
cu n-1 ori. Procedurile de ocupare şi eliberare de blocuri vor fi mai complicate, dar acest neajuns<br />
este compensat prin reducerea numărului de accese la disc. De aici până la evidenţa spaţiului liber<br />
printr-o structură arborescentă nu este decât un pas.<br />
Alocarea spaţiului pentru fişiere disc. Cele mai cunoscute metode de alocare a spaţiului<br />
pentru fişiere sunt: alocarea contiguă, alocarea înlănţuită şi alocarea indexată.<br />
a) Alocarea contiguă cere ca fiecare fişier să ocupe un set de adrese consecutive pe disc.<br />
În descriptorul de fişier din director se depune adresa de început şi lungimea zonei alocate.<br />
Exemplul prezentat ilustrează acest tip de alocare pentru cele 5 fişiere. Problema principală care<br />
apare este fragmentarea; se efectuează compactarea în aceleaşi condiţii ca cele întâlnite la<br />
gestiunea memoriei. Acest tip de alocare se foloseşte la SO SIRIS şi parţial la RSX.<br />
b) Alocarea înlănţuită se foloseşte pentru a elimina fragmentarea. În acest caz, fiecare<br />
fişier este înregistrat într-un şir de blocuri legate între ele printr-o listă înlănţuită. În figura
- 83 -<br />
următoare ordinea blocurilor pentru fişierul F este 9, 16, 1, 10, 25. Alăturat adresei blocului este<br />
încadrat pointerul la blocul următor.<br />
DIRECT OR:<br />
00<br />
04<br />
08<br />
01 10 02<br />
05 06<br />
09 16 10<br />
25<br />
03<br />
07<br />
11<br />
Fişier Început Sfârşit<br />
F 9 25<br />
12<br />
13 14<br />
15<br />
16<br />
20<br />
01<br />
17 18<br />
21 22<br />
19<br />
23<br />
24<br />
25 -1 26<br />
27<br />
28<br />
29 30<br />
31<br />
Principalul dezavantaj al metodei este că permite doar acces secvenţial la fişiere. Acest mod de<br />
alocare se utilizează la fişierele secvenţial-înlănţuite sub SO SIRIS.<br />
c) Alocarea indexată. Acest mod de alocare înlătură dezavantajul accesului secvenţial de<br />
la alocarea înlănţuită. Pe lângă blocurile ataşate fişierului, la crearea fişierului se creează un bloc<br />
special, bloc de index în care se trec în ordine adresele tuturor sectoarelor ocupate de fişierul<br />
respectiv. În figura de mai jos este ilustrat acest mod de alocare pentru fişierul F.<br />
DIRECT OR:<br />
00<br />
04<br />
08<br />
01 02<br />
05 06<br />
09 10<br />
03<br />
07<br />
11<br />
Fişier Index Nr.blocuri<br />
F 19 5<br />
12<br />
16<br />
20<br />
24<br />
13 14<br />
17 18<br />
21 22<br />
25 26<br />
15<br />
19<br />
23<br />
27<br />
19<br />
09<br />
16<br />
01<br />
10<br />
25<br />
-1<br />
28<br />
29 30<br />
31<br />
În descriptorul fişierului există un pointer către blocul de index. Dacă fişierul este mare şi<br />
ocupă mai multe adrese decât încap într-un bloc, atunci se creează mai multe blocuri de index
- 84 -<br />
legate într-o listă înlănţuită. Această metodă este aplicată la SO CP/M, RSX şi UNIX. UNIX<br />
oferă o schemă de alocare indexată pe trei nivele, deosebit de eficientă.<br />
2.3.6. Particularităţi SGF ale unor SO particulare<br />
În cele ce urmează se vor studia sistemele de fişiere ale SO UNIX, MS_DOS. Se va trata<br />
mai întâi relaţia cu utilizatorul( specificări de fişiere...) şi apoi se va prezenta structura internă de<br />
reprezentare a fişierelor pe discuri.<br />
Sistemul de fişiere UNIX. În legătură cu SGF sub UNIX se vor avea în vedere<br />
următoarele:<br />
A- convenţii privind specificarea unui nume de fişier<br />
B- structura arborescentă de fişiere şi extensiile ei<br />
C- structura internă a discului.<br />
A. Specificarea unui fişier UNIX. Un fişier UNIX este specificat printr-un şir de 14<br />
caractere ASCII cu anumite restricţii impuse de componenta shell. Printre caracterele interzise în<br />
nume de fişier sunt şi caracterele “>“ “
- 85 -<br />
În momentul intrării în sistem, fiecare utilizator indică directorul lui, care este fixat ca<br />
director curent (home directory). În mod normal fiecare utilizator îşi dezvoltă propria structură<br />
arborescentă în directorul propriu. Există cel puţin trei excepţii:<br />
a) se doreşte utilizarea unei structuri arborescente de către mai mulţi utilizatori. În acest<br />
caz utilizatorul dă o comandă de schimbare a directorului curent; este bine ca administratorul<br />
sistemului să aibă cunoştinţă de acest fapt pentru fixarea corespunzătoare a parolelor şi a<br />
drepturilor de acces.<br />
b) se doreşte utilizarea în comun a unui fişier obişnuit ce are în structură mai mulţi<br />
directori părinte. Partajarea este permisă pentru fişiere, dar nu şi pentru directori. Căile de<br />
recunoaştere a fişierului se specifică după cum s-a prezentat în 2.3.5. La legarea multiplă apare<br />
următoarea problemă: ce se întâmplă dacă un utilizator vrea să ştergă fişierul? Acest fişier trebuie<br />
să rămână activ dacă e şters numai de către unul dintre utilizatori. Pentru aceasta în descriptorul<br />
de fişier există un câmp numit contor de legare care are valoarea 1 la crearea fişierului şi a cărui<br />
valoare creşte cu 1 la fiecare nouă legătură. La ştergere se radiază legătura cu părintele ce a cerut<br />
ştergerea şi contorul scade cu 1. Dacă contorul a ajuns la zero, fişierul se şterge de pe disc.<br />
c) se doreşte legarea la un anumit subdirector a unui sistem de directori aflat pe un alt<br />
periferic. În specificarea fişierelor nu apare zona de periferic. Acest lucru se datorează faptului că<br />
sub UNIX se folosesc operaţiile de montare şi demontare a unui sistem de fişiere. Operaţia de<br />
montare constă în conectarea unui sistem de fişiere de pe un anumit disc la un director vid<br />
existent pe sistemul de fişiere de pe discul implicit. Pentru montare se dă o comandă privilegiată<br />
UNIX. De exemplu, prin comanda<br />
#/etc/mount /dev/fd3 /b<br />
se indică legarea discului al căriu fişier special( driver) poartă numele fd3( şi care se referă la<br />
discul nr. 3) la directorul vid /b.<br />
La încărcarea SO UNIX se face automat o operaţei de montare. Pe discul sistem directorul root<br />
are subdirectorul usr vid. Conţinutul complet al directorului usr se racordează la root printr-o<br />
operaţie de montare. Operaţia de montare se face şi la utilizarea SO UNIX în reţea.<br />
C. Structura internă a discului UNIX. Un fişier UNIX este o colecţie de octeţi, fiecare<br />
octet putând fi adresat individual. Un sistem de fişiere UNIX este o structură de date rezidentă pe<br />
disc. Un disc este compus din patru categorii de blocuri.
- 86 -<br />
Blocul 0 - bloc de boot<br />
Blocul 1 - Superbloc<br />
Blocul 2 - inod<br />
Blocul n - inod<br />
Blocul n+1 zona fişier<br />
Blocul n+m zona fişier<br />
Blocul 0 conţine programul de încărcare al SO, dependent de maşina pe care se lucrează.<br />
Blocul 1 conţine o serie de informaţii prin care se defineşte sistemul de fişiere de pe disc,<br />
printre care<br />
- numărul n de inoduri<br />
- numărul de zone definite pe disc<br />
- pointeri spre harta de biţi a alocării inodurilor<br />
- pointeri spre harta de biţi a spaţiului liber disc<br />
- dimensiunile zonelor disc etc.<br />
De asemenea, acest bloc conţine şi evidenţa spaţiului liber de pe disc prin metoda fişierului<br />
invers.<br />
Blocurile de la 2 la n, unde n este o constantă a formatării discului, conţin inoduri. Un<br />
inod( sau i-nod) este numele UNIX a descriptorului unui fişier, conţine 64 octeţi, iar inodurile<br />
sunt memorate pe disc sub forma unei liste( numită i-listă). Numărul de ordine al unui i-nod în<br />
cadrul i-listei se reprezintă pe 2 octeţi, se numeşte i-număr şi constituie legătura dintre fişier şi<br />
programele utilizator.<br />
Partea cea mai mare a discului este rezervată zonei fişierelor. Alocarea spaţiului pentru<br />
fişiere se face printr-o variantă de indexare. Informaţiile de plecare pentru alocare sunt fixate în i-<br />
noduri.<br />
Structura intrării într-un fişier director este următoarea:<br />
Numele fisierului<br />
Inumar<br />
0 13 14 15<br />
În director se găseşte de fapt inodul corespunzător. Un inod conţine( printre altele) informaţiile:<br />
- identificarea proprietarului fişierului<br />
- identificarea grupului de utilizatori<br />
- biţii de protecţie<br />
- lungimea fişierului<br />
- data creării şi a ultimei actualizări<br />
- numărul de legături la fişiere<br />
- indicarea faptului că fişierul este un director<br />
- pointerii spre blocurile ataşate fişierului.<br />
Structura pointerilor spre blocurile ataşate fişierului este prezentată în figura următoare:<br />
Inod:<br />
Identificare<br />
0 1 2 3 4 5 6 7 8 9 A B C<br />
Indirectare<br />
Regasire<br />
directa
- 87 -<br />
În inodul fişierului se află şi o listă cu 13 intrări care desemnează blocurile fizice<br />
aparţinând fişierului. Primele 10 intrări conţin adresele primelor 10 blocuri de câte 512 octeţi ale<br />
fişierului. Intrarea 11 conţine adresa unui bloc numit bloc de indirectare simplă care conţine<br />
adresele următoarelor 128 blocuri a câte 512 octeţi ale fişierului. Intrarea 12 conţine adresa<br />
blocului de indirectare dublă care conţine adresele a 128 blocuri de tip indirectare simplă, iar<br />
intrarea 13 conţine adresele a 128 blocuri de indirectare dublă.<br />
Numărul de accese necesare pentru a obţine direct un octet oarecare este cel mult 4.<br />
Pentru fişiere mici acest număr este mai mic. În tabelul următor este dat numărul maxim de<br />
accese la disc pentru a obţine un octet, în funcţie de lungimea fişierului:<br />
Lungime maximă<br />
în blocuri<br />
Lungime maximă<br />
octeţi<br />
în<br />
Accese indirecte<br />
Accese la<br />
bloc de<br />
informaţie<br />
10 5120 - 1 1<br />
10+128= 138 70656 1 1 2<br />
2<br />
10 128 128<br />
<br />
16522<br />
8459264 2 1 3<br />
2<br />
10 128 128<br />
<br />
3<br />
128 2113674<br />
1082201088 3 1 4<br />
Total<br />
accese<br />
D. Mecanismul de acces la fişier. Înainte ca un fişier să fie accesat el trebuie să fie<br />
deschis. Ca efect al deschiderii este actualizată structura de date următoare din figura următoare.<br />
Astfel, inumărul fişierului deschis este trecut, dacă nu există deja, în tabela de inoduri active din
- 88 -<br />
sistem. Sistemul întreţine în paralel o tabelă de fişiere a sistemului ce conţine descriptorii tuturor<br />
fişierelor active din sistem.<br />
Fiecare proces conţine câte un pointer spre această tabelă pentru fiecare fişier pe care îl<br />
are deschis. Se ştie că un proces fiu moşteneşte toate fişierele deschise de părinte. Această<br />
folosire comună se realizează prin pointerul comun spre tabela de fişiere a sistemului.<br />
Proces a<br />
Procese<br />
Tabela de<br />
fişiere a<br />
sistemului<br />
Tabela de<br />
inoduri<br />
Fişiere<br />
Proces b<br />
Fiecare proces<br />
Proces c<br />
Descriptori de<br />
fişiere deschise<br />
Fişiere MS_DOS. Dată fiind popularitatea acestui SO se va studia mai detaliat sistemul<br />
său de fişiere. Se vor avea în vedere:<br />
A. Organizarea şi specificare fişierelor MS_DOS.<br />
B. Structura internă a unui disc DOS.<br />
C. Partiţionarea unui hard disc în discuri logice.<br />
D. Structura şi alocarea spaţiului la un disc logic.<br />
E. Structura şi reprezentarea unui director.<br />
F. Manipularea fişierelor şi articolelor.<br />
A. Organizarea şi specificarea fişierelor MS_DOS. Începând cu versiunea 2.0, SO<br />
MS_DOS adoptă un sistem de fişiere organizat arborescent( acest mod de organizare a fost<br />
descris în paragraful 2.3.5). Specificarea numelui unui fişier se încadrează în specificarea din<br />
paragraful 2.3.1. din care lipseşte zona de versiune.<br />
În forma cea mai simplă, un fişier obişnuit, ca şI un fişier director, se specifică la fel ca şi<br />
sub CP/M, adică: nume.tip<br />
unde nume are maximum 8 caractere, iar tip are maximum 3 caractere; numele şI tipul pot conţine<br />
orice caractere cu excepţia caracterelor “ / \ [ ] : ¦ < > + = ; ,<br />
Fişierele speciale MS_DOS au nume predefinite, iar aceste nume nu pot fi folosite ca şi<br />
nume de fişiere. Numele rezervate sunt:<br />
- CON desemnează tastatura, dacă este folosit ca fişier de intrare, respectiv ecranul dacă<br />
este folosit ca fişier de ieşire.<br />
- PRN( cu sinonimul LPT1), LPT2, LPT3 desemnează între una şi trei imprimante<br />
paralele.<br />
- AUX( cu sinonimul COM1), COM2, COM3 şI COM4 desemnează între unul şi patru<br />
adaptoare de comunicaţii asincrone.
- 89 -<br />
- NUL este numele unui fişier( echipament) fictiv; folosit pe post de fişier de intrare<br />
generează imediat pentru SGF marcajul de sfârşit de fişier, iar folosit pe post de fişier de ieşire,<br />
informaţiile “scrise” în el nu sunt de fapt depuse nicăieri.<br />
Aceste nume pot( dar nu este obligatoriu) să fie urmate de “:” .<br />
În forma cea mai generală, un fişier pe suport disc( dischetă, hard sau ramdrive, adică<br />
simularea unui disc în memoria RAM) se specifică prin cele patru zone, adică:<br />
[periferic][cale]nume[.tip]<br />
unde<br />
periferic se va specifica printr-o literă urmată de “:”. DOS poate avea maximum 26 de<br />
periferice de tip disc, notate cu literele alfabetului, începând cu A; în mod obligatoriu literele A:<br />
şI B: desemnează dischete; primul hard disc va fi notat cu C:, apoi pot urma şI alte periferice de<br />
tip disc. Dacă lipseşte specificarea de periferic se presupune că este vorba despre perifericul<br />
implicit.<br />
cale indică succesiunea de directori de la rădăcină până la fişier( dacă începe cu “\”) sau<br />
de la directorul curect până la fişier. Separarea directorilor se face prin simbolul “\”. Dacă<br />
specificarea de cale lipseşte se presupune că fişierul se găseşte în directorul curent. SO MS_DOS<br />
reţine câte un director curent pentru fiecare periferic disc din sistem.<br />
tip se foloseşte în general pentru a indica conţinutul fişierului şi poate lipsi.<br />
Unele comenzi DOS acceptă specificarea generică de fişiere prin folosirea în zona de<br />
nume, de tip sau în ambele a simbolurilor speciale ““ sau “?”( după cum s-a descris în capitolele<br />
anterioare).<br />
B. Structura internă a unui disc MS_DOS. În sistemul MS_DOS unitatea de alocare a<br />
spaţiului pe disc este clusterul. Un cluster este o succesiune de 1 până la 8 sectoare vecine,<br />
alocate împreună aceluiaşi fişier. Dimensiunea unui cluster este o constantă care depinde de tipul<br />
discului şi de tipul SC, de exemplu:<br />
- dischetă simplă faţă: 1 sector/ cluster<br />
- dischetă dublă faţă: 2 sectoare/ cluster<br />
- hard disc pe IBM PC/AT: 4 sectoare/ cluster<br />
- hard disc pe IBM PC/XT: 8 sectoare/ cluster.<br />
Pentru a descrie modul în care un fişier utilizează clusterii unui disc fizic, este necesară<br />
parcurgerea mai multor etape( în maniera “top-down”):<br />
1. partiţionarea unui disc în discuri logice<br />
2. structura şi alocarea spaţiului la un disc logic<br />
3. structura şi reprezentarea unui director<br />
4. manipularea fişierelor şi articolelor.<br />
C. Partiţionarea unui hard disc. Spaţiul unui hard disc poate fi împărţit în cel mult<br />
patru zone contigue numite partiţii. O partiţie conţine un număr oarecare de cilindri consecutivi.<br />
SO MS_DOS priveşte de la versiunea 3.30 fiecare partiţie ca pe un disc separat. Două partiţii ale<br />
aceluiaşi disc pot conţine sisteme de operare diferite. Operaţia de partiţionare se realizează cu<br />
ajutorul unui program specializat numit FDISK. Există şi alte programe ce realizează printre<br />
altele partiţionarea unui hard disc, dintre acestea amintim mediul de întreţinere a discului numit<br />
DM( Disk Manager). Prin operaţia de partiţionare se pierd toate informaţiile de pe discul<br />
respectiv, deci înainte de partiţionare trebuie salvate informaţiile utile. Operaţia de partiţionare a<br />
unui hard disc este bine să fie făcută numai de persoane ce au cunoştinţe serioase despre sisteme<br />
de operare.<br />
Se va prezenta în continuare modul de implementare a mecanismului de partiţionare.<br />
Primul sector al hard discului( sectorul 1 de pe faţa 0 a cilindrului 0) se numeşte sectorul de<br />
încărcare absolut sau sectorul MBR( Master Boot Record). El conţine un program de tip<br />
bootstrap şi o tabelă de descriere a partiţionării.<br />
Structura acestui sector este următoarea:<br />
000:<br />
1BE:<br />
Programul bootstrap de partitionare<br />
descriere partitia 1<br />
descriere partitia 2
- 90 -<br />
O intrare pentru descrierea unei partiţii are structura următoare:<br />
B Hi S+Ci Sy Hf S+Cf Sectreli Sectrelf<br />
00 01 02 04 05 06 08 0C 0F<br />
unde<br />
B este octetul de indicare a partiţiei active; valoarea 80 indică o partiţie activa, iar<br />
valoarea 00 indică o partiţie inactivă. În orice moment pe disc trebuie să existe o singură partiţie<br />
activă.<br />
Hi şi S+Ci indică adresa fizică de început a partiţiei. Se indică numărul feţei pe primul<br />
octet, iar pe următorii doi, numărul sectorului şi al cilindrului de început.<br />
Hf şi S+Cf indică, analog cu cele de mai sus, adresa fizică de sfârşit a partiţiei.<br />
Sectreli şI Sectrelf indică numărul sectorului de început, respectiv al sectorului de sfârşit<br />
a partiţiei. Pe hard disc sectoarele fizice sunt numerotate începând cu 1. Formula de calcul pentru<br />
numărul relativ al sectorului este:<br />
Nrelsect= ( nrcilindru sectpecil cap)+ ( nrcap sectpecil)+ ( nrsector-1).<br />
Sy indică tipul sistemului şi poate lua valorile:<br />
1 partiţie DOS cu FAT pe 12 biţi<br />
4 partiţie DOS cu FAT pe 16 biţi<br />
5 partiţie DOS extinsă<br />
0 tip de partiţie nedefinit( pentru DOS).<br />
Încărcarea unui SO aflat într-o partiţie activă se face în felul următor: în momentul<br />
iniţializării, BIOS încarcă în memorie sectorul MBR şi dă controlul programului bootstrap de<br />
partiţionare. Acesta citeşte tabela de partiţii şi o caută pe cea activă; având adresa fizică de<br />
început a acesteia, citeşte primul sector al ei. În acest sector se află programul bootstrap de<br />
lansare a încărcării SO respectiv. De aici încărcarea se face cum s-a descris deja.<br />
Fiecare SO aflat pe hard disc dispune de un program similar lui FDISK. Prin intermediul<br />
lui se poate dezactiva o partiţie şi activa alta; deci la o nouă încărcare poate intra în lucru alt SO.<br />
D. Structura şi alocarea spaţiului la un disc logic. Un disc logic este fie o dischetă, fie<br />
o partiţie de hard disc, fie un ramdrive. Un disc logic este împărţit în patru zone: zona de boot,<br />
tabela de alocare a fişierelor( FAT), directorul rădăcină şi zona celorlalte fişiere:
Informatii de identificare, tabela BPB, rutina Bootstrap<br />
Zona rezervata<br />
Tabela FAT<br />
- 91 -<br />
Eventuale copii ale FAT<br />
Directorul ROOT<br />
Zona de fisiere<br />
Zona de boot conţine informaţii utilizate de fiecare dată când se încarcă sistemul de<br />
operare şi dependente de sistem. Structura zonei este următoarea:<br />
00<br />
03<br />
Instructiune de salt la rutina Boot<br />
Nume SO si numarul de versiune<br />
0B<br />
0D<br />
0E<br />
10<br />
11<br />
13<br />
15<br />
16<br />
18<br />
1A<br />
1C<br />
1E<br />
numar de octeti / sector<br />
numar sectoare / cluster<br />
lungimea zonei rezervate<br />
numar de tabele FAT<br />
numar de intrari în ROOT<br />
total sectoare / volum<br />
octet de descriere a discului<br />
numar de sectoare / FAT<br />
numar de sectoare / pista<br />
numar de fete ale discului<br />
numar de sectoare ascunse<br />
Rutina de Boot<br />
Tabela BPB<br />
BIOS<br />
Parameter<br />
Bloc<br />
În tabela BPB se află toate informaţiile necesare structurării discului. La adresa 0E se<br />
trece dimensiunea zonei de după sectorul Boot şi până la începutul tabelei FAT; la adresa 1C,<br />
numărul de sectoare ascunse reprezintă numărul sectoarelor de pe discul fizic înainte de sectorul<br />
Boot. La dischetă numărul este 0, iar la hard disc este numărul sectoarelor din faţa partiţiei DOS<br />
respective. La adresa 15 este un octet de descriere a discului( se precizează dacă este dischetă sau<br />
hard disc, număr feţe,...).<br />
Tabela de alocare a fişierelor( FAT File Alocation Table) conţine informaţii de alocare a<br />
spaţiului pe disc pentru fiecare fişier. Sub DOS evidenţa spaţiului liber se face prin metoda<br />
fişierului invers, iar alocarea este de tip indexat. Tabela FAT conţine atâtea intrări câţi clusteri<br />
există pe disc, dacă există mai puţin de 4097 clusteri atunci fiecare intrare ocupă 12 biţi, în caz<br />
contrar 6 biţi. Fiecare intrare în FAT poate avea una din următoarele valori( cifra din paranteză<br />
apare numai dacă intrarea ocupă 16 biţi):<br />
(0)000 dacă clusterul respectiv e liber<br />
(F)FF0 la (F)FF6 dacă clusterul este rezervat de DOS<br />
(F)FF7 dacă clusterul este defect<br />
(F)FF8 la (F)FFF dacă este ultimul cluster al unui fişier<br />
orice altă valoare indică faptul că clusterul este ocupat de un fişier, iar valoarea indică<br />
numărul clusterului următor ocupat de acelaşi fişier( ocuparea se indică cu ajutorul unei liste<br />
înlănţuite).<br />
Directorul rădăcină are o lungime fixă precizată la formatare. În mod implicit, numărul<br />
de intrări pentru directorul rădăcină este următorul:<br />
64 pentru dischete simplă faţă<br />
112 pentru dischete dublă faţă de 360- 720 Ko
- 92 -<br />
224 pentru dischete high-density 1.2- 1.44 Mo<br />
512 pentru hard disc.<br />
În acest director trebuie să existe o intrare care să furnizeze eticheta de volum, iar dacă<br />
discul este disc sistem, primele două intrări trebuie să conţină descriptorii fişierelor sistem<br />
IBMBIO.COM şi IBMDOS.COM.<br />
Zona fişierelor conţine celelalte fişiere. Lungimea oricărui fişier este limitată de<br />
capacitatea discului.<br />
E. Structura şi reprezentarea unui director. Un director conţine câte o intrare pentru<br />
fiecare fişier subordonat lui( subordonaţii pot fi fişiere sau subdirectoare). Fiecare intrare într-un<br />
director conţine descriptorul fişierului subordonat. Un descriptor de fişier sub DOS ocupă 32<br />
octeţi şi are structura:<br />
00<br />
08<br />
0B<br />
0C<br />
16<br />
18<br />
1A<br />
1C<br />
Numele fisierului<br />
Tipul fisierului<br />
Atributele fisierului<br />
10 octeti rezervati<br />
Ora crearii<br />
Data crearii<br />
Numarul clusterului de start<br />
Lungimea fisierului( 4 octeti)<br />
Numele şi tipul fişierului sunt reprezentate în cod ASCII. Primul octet din descriptor( care<br />
coincide cu primul caracter al numelui) indică şi faptul că fişierul este şters sau nu. Semnificaţiile<br />
posibile ale primului caracter sunt:<br />
- codul 00 indică o intrare în director încă nefolosită<br />
- codul E5 indică descriptorul unui fişier care a fost şters<br />
- caracterul “.” indică descriptorul directorului curent sau al părintelui<br />
- orice alt caracter indică descriptorul unui fişier subordonat.<br />
La crearea de noi fişiere se utilizează întâi descriptorii de fişiere şterse( în disciplina FIFO) după<br />
care se ocupă noi intrări.<br />
Atributele fişierului au fost prezentate în paragraful 2.3.3.<br />
Ora creării se reprezintă pe 16 biţi: biţii 0-4 reprezintă secundele numărate din doi în doi,<br />
biţii 5-A conţin minutele, iar biţii B-F conţin ora.<br />
Data creării se reprezintă pe 16 biţi: 0-4 numărul zilei în lună, 5-8 numărul lunii în an, 9-<br />
F diferenţa dintre anul curent şi 1980.<br />
Clusterul de start este capul listei înlănţuite din FAT ce indică în ordine clusterii ocupaţi<br />
de fişier.<br />
Lungimea fişierului este exprimată în număr de octeţi( şi se reprezintă pe 4 octeţi).<br />
F. Manipularea fişierelor şi articolelor. SO DOS are multe elemente preluate de la<br />
CP/M şi UNIX, SGF DOS adoptă în consecinţă două moduri de gestiune a fişierelor:<br />
Setul de funcţii compatibile CP/M utilizează un FCB( File Control Bloc). Acesta se<br />
creează în zona de memorie utilizator, are 37 octeţi cu o extindere specială de încă 7. Mecanismul<br />
FCB permite numai lucrul cu fişiere din directorul curent pentru că nu recunoaşte structura<br />
arborescentă.<br />
Setul de funcţii compatibile UNIX utilizează conceptul de handle( identificator, număr<br />
logic). La deschiderea fişierului se transmite SGF specificarea completă a fişierului( se precizează<br />
perifericul, calea, numele şi tipul acestuia). Tabelul de legătură dintre fişier şi program este<br />
memorat într-o zonă sistem. Utilizatorul primeşte după deschidere un cod pe 16 biţi numit handle.<br />
Prin intermediul acestui cod se vor face în continuare toate referirile la fişier.
- 93 -<br />
Ambele seturi de funcţii permit efectuarea operaţiilor de citire şi scriere la nivel de<br />
articol( bloc) în acces secvenţial şi direct. Primitivele oferite de limbajele de nivel înalt pentru<br />
lucrul cu fişiere fac transparentă pentru utilizator diferenţa dintre funcţiile FCB şi cele handle.
- 94 -<br />
2.4. SUBSISTEMUL DE PLANIFICARE AL SO<br />
2.4.1. Probleme generale privind planificarea<br />
Conceptul de planificare. Planificarea are în vedere utilizarea eficientă a CPU şi<br />
asigurarea unui timp de răspuns rezonabil pentru toţi utilizatorii. În sistemele cu<br />
multiprogramare, planificarea( CPU Scheduling) este o componentă de bază a SO( prin<br />
comutarea CPU între procese SC devine mai productiv). Există trei nivele de planificare<br />
în SO: - planificare pe termen lung;<br />
- planificare pe termen mediu;<br />
- planificare pe termen scurt.<br />
Fiecare nivel de planificare acţionează în funcţie de stările procesului astfel:<br />
Planificarea pe termen lung are drept sarcină alegerea lucrării care urmează a fi<br />
executată, alocarea resurselor necesare acesteia şi crearea proceselor corespunzătoare<br />
pentru această lucrare. La terminarea lucrării, planificatorul de lucrări eliberează resursele<br />
şi distruge procesele aferente. La acest nivel planificarea acţionează cu frecvenţa cea mai<br />
mică( o schimbare intervine la câteva minute). Un astfel de planificator trebuie să separe<br />
tipurile de joburi în funcţie de solicitări: joburi cu multe I/O, dar cu timp CPU redus(<br />
programe de gestiune), joburi cu I/O limitate, dar cu multe calcule( programe tehnicoştiinţifice,<br />
de simulare) etc. În acest caz planificatorul colaborează cu componenta<br />
SPOOLING.<br />
Planificarea pe termen mediu. În unele sisteme planificarea pe termen lung are rol<br />
minim sau poate fi absentă. De exemplu în sistemele time-sharing nu are sens o astfel de<br />
planificare. La aceste sisteme precum şi la cele cu memorie virtuală se aplică tehnica<br />
swapping, prin care procesele sunt trecute din starea RUN în starea SWAP şi din SWAP<br />
în READY. Prin aceste evacuări temporare scade gradul de multiprogramare, se<br />
prelungeşte durata execuţiei, în schimb se permite accesul simultan al mai multor<br />
utilizatori în sistem. Planificatorul este cel care decide momentele în care se fac<br />
evacuările şi care procese se vor evacua sau readuce în memorie.<br />
Planificarea pe termen scurt are în vedere trecerea alternativă a proceselor din<br />
starea READY în starea RUN şi invers. La acest nivel se încadrează activitatea<br />
dispecerului de procesoare şi acţiunile SO şi SC pentru planificarea accesului la discurile<br />
magnetice.<br />
Acţiunea unui planificator trebuie privită sub două aspecte: pe de o parte<br />
regulile de acţiune după care se ghidează pentru a-şi realiza sarcinile, pe de altă parte<br />
implementarea lui în contextul întregului SO.<br />
Fixarea sarcinilor unui planificator se face precizând trei aspecte:<br />
- modalitatea de intervenţie<br />
- funcţia de prioritate<br />
- regula de arbitraj.<br />
Aceste reguli fiind stabilite planificatorul funcţionează astfel: la anumite momente de<br />
timp, stabilite de baza modalităţii de intervenţie evaluează funcţia de prioritate pentru<br />
fiecare proces din sistem. Drept urmare, fiecare proces primeşte o prioritate de utilizare a<br />
CPU. În cazul în care două procese au aceeaşi prioritate, regula de arbitraj fixează care<br />
dintre ele intră în starea RUN.
- 95 -<br />
Modalitatea de intervenţie stabileşte momentele în care planificatorul intră în<br />
acţiune. Există două modalităţi de intervenţie:<br />
- la momentele impuse de proces: planificatorul intră în lucru atunci când un<br />
proces îşi termină activitatea sau când aşteaptă terminarea unei operaţii de I/O. Acest tip<br />
de planificare se foloseşte la lucrul în multiprogramare;<br />
- la momentele impuse de către SO: în acest caz SO intervine indiferent de starea<br />
proceselor pe care le planifică. SO UNIX adoptă un astfel de mecanism.<br />
Funcţia de prioritate are ca argumente procesele şi parametrii sistemului.<br />
Determinarea priorităţii se face în funcţie de următoarele criterii:<br />
- cererea de memorie;<br />
- atingerea unui timp de servire de către CPU;<br />
- timpul real din sistem;<br />
- timpul total de servire;<br />
- valorile unor priorităţi externe;<br />
- necesarul de timp rămas până la terminarea procesului etc.<br />
Algoritmii de planificare trebuie să îndeplinească două calităţi:<br />
- să realizeze scopurile de performanţă pentru care au fost elaboraţi;<br />
- să aibă o durată foarte mică de execuţie, pentru a nu creşte în mod nejustificat<br />
timpul de regie al SO.<br />
Regula de arbitraj stabileşte o ordine în caz de priorităţi egale. De regulă, se alege<br />
una dintre următoarele variante posibile:<br />
- servirea în ordine cronologică(FIFO);<br />
- servirea circulară;<br />
- servirea aleatoare.<br />
Implementarea planificatoarelor. Toate tipurile de planificatoare sunt<br />
implementate prin intermediul semafoarelor şi fac uz de facilităţile oferite de gestiunea<br />
memoriei. În funcţie de tipul SO, planificatoarele deţin module specializate de alocare şi<br />
eliberare a resurselor, prevenire, detectare şi eventual ieşire din impas.<br />
Referitor la relaţia dintre planificator şi procesele pe care le planifică, există două<br />
posibilităţi:<br />
- planificator partajat atunci când fiecare dintre procese îl apelează ca pe un<br />
subprogram; în acest caz modalitatea de intervenţie este dictată de către procese;<br />
p1 p2 pn<br />
. . .<br />
S S S<br />
- planificator master atunci când acesta lansează şi suspendă procesele pe care le<br />
planifică; evident atunci că modalitatea de intervenţie este fixată de către SO.<br />
p1 p2 . . .<br />
pn
- 96 -<br />
S<br />
2.4.2. Planificarea proceselor<br />
Sarcinile planificatorului de procese. În funcţie de nivelul la care lucrează<br />
planificatorul, SO trebuie să-i ofere toate informaţiile de care are nevoie. În acest scop,<br />
fiecare proces este reprezentat în sistem printr-un bloc de control al procesului prescurtat<br />
PCB( Process Control Bloc).<br />
Pe termen lung, planificatorul trebuie să găsească în PCB următoarele informaţii:<br />
- identificare job;<br />
- starea curentă a jobului;<br />
- prioritatea( prefixată la unele SO);<br />
- timpul de lucru estimat pentru job;<br />
- resursele necesare.<br />
Pe baza acestor informaţii planificatorul decide trecerea unui job din starea HOLD în<br />
starea READY. Planificarea se face astfel încât să fie atins unul din obiectivele:<br />
- minimizarea timpului mediu de răspuns;<br />
- maximizarea factorului de utilizare a resurselor;<br />
- asigurarea unei rate medii de servire a joburilor.<br />
Pe termen scurt se decide trecerea din starea READY în starea RUN şi invers.<br />
Principalele sarcini de planificare sunt:<br />
- ţine evidenţa tuturor proceselor din sistem;<br />
- decide la care proces îi atribuie procesor şi pentru cât timp;<br />
- alocă procesului un procesor;<br />
- eliberează procesorul la ieşirea procesului din starea RUN.<br />
Pentru aceasta, în PCB trebuie să apară, printre altele, informaţiile:<br />
- starea procesului;<br />
- pointer la următorul PCB în aceeaşi stare;<br />
- numărul procesului( acordat de planificator);<br />
- contorul de program( adresa instrucţiunii maşină ce urmează a fi executată);<br />
- o zonă pentru copia regiştrilor generali ai maşinii;<br />
- limitele zonei( zonelor) de memorie alocate procesului;<br />
- lista fişierelor deschise etc.<br />
Toate PCB sunt memorate într-o zonă de memorie proprie planificatorului de<br />
procese,. Starea unui proces poate fi RUN, READY, WAIT sau SWAP. Procesele din<br />
aceeaşi stare sunt înlănţuite între ele.Deoarece toate procesele folosesc registrele generale<br />
ale procesorului, este necesar ca la ieşirea din starea RUN conţinutul acestora să fie<br />
salvat. La o nouă intrare în RUN se reface conţinutul registrelor generale. Iată cum arată<br />
un schimb READY-RUN între două procese A şi B:<br />
Proces A<br />
RUN<br />
Planificator<br />
Salvează regiştrii A<br />
Actualizare PCB A<br />
READY<br />
Proces B<br />
READY<br />
Actualizare PCB B<br />
Refacere regiştrii B<br />
RUN
- 97 -<br />
În sarcina planificatorului de procese<br />
În sarcina planificatorului de procese stă şi organizarea cozilor la perifericele I/O.<br />
În figura următoare este prezentat un ansamblu de cozi proprii planificatorului de<br />
procese:
- 98 -<br />
READY:<br />
READY<br />
PCB7<br />
READY<br />
PCB2<br />
MM0:<br />
WAIT<br />
WAIT<br />
WAIT<br />
MM1:<br />
PCB3<br />
PCB1<br />
PCB8<br />
DK0:<br />
WAIT<br />
PCB5<br />
TT0:<br />
RUN:<br />
RUN<br />
PCB6<br />
RUN<br />
PCB4<br />
(biprocesor)<br />
Algoritmi de planificare. Optimizarea în ansamblu a criteriilor amintite este<br />
practic imposibilă; optimizarea unui criteriu provoacă înrăutăţirea rezultatelor altuia.<br />
Algoritmii încearcă realizarea unui compromis între criterii. Cei mai utilizaţi algoritmi de<br />
planificare sunt prezentaţi în continuare.<br />
FCFS( First Come First Served) sau FIFO( First In First Out) primul venitprimul<br />
servit. Lucrările sunt servite în ordinea lor cronologică. Algoritmul este simplu,<br />
dar nu prea eficient.<br />
De exemplu, presupunem că există 3 joburi cu următorii timpi de execuţie:<br />
- jobul 1 durează 24 minute;<br />
- jobul 2 durează 3 minute;<br />
- jobul 3 durează 3 minute.<br />
Dacă joburile sosesc la sistem în ordinea 1, 2, 3 atunci timpul mediu de servire este:<br />
24 27 30<br />
27 min ute .<br />
3<br />
Dacă joburile sosesc în ordinea 2, 3, 1 timpul mediu de servire este:<br />
3 6<br />
30<br />
13 minute<br />
3<br />
SJF( Shortest Job First). Se execută primul jobul care consumă cel mai puţin timp<br />
CPU; acest algoritm are dezavantajul că presupune cunoaşterea exactă a timpului CPU<br />
necesar execuţiei procesului.<br />
Algoritmul bazat pe priorităţi este cel mai des folosit; ceilalţi algoritmi sunt cazuri<br />
particulare ale acestuia. Fiecare job primeşte un număr de prioritate. Joburile se<br />
ordonează după priorităţi şi apoi se execută în această ordine. Se disting două metode de<br />
stabilire a priorităţilor:<br />
a) jobul primeşte prioritatea la intrarea în sistem şi o păstrează până la sfârşit.<br />
Această variantă se întâlneşte foarte des, dar are dezavantajul că dacă sunt multe joburi<br />
cu prioritate mare atunci cele cu prioritate mică aşteaptă nedefinit.
- 99 -<br />
b) SO calculează priorităţile după reguli proprii şi le ataşează dinamic proceselor<br />
în execuţie; această variantă se foloseşte mai ales la planificarea pe termen mediu. Din<br />
această categorie se disting doi algoritmi:<br />
- jobul cel mai vechi din sistem se va executa primul;<br />
- jobul cel mai vechi rezident în memorie se execută primul.<br />
Al doilea algoritm este implementat la SO UNIX. La interval de o secundă se opreşte<br />
activitatea sistemului şi se recalculează pentru fiecare proces p i prioritatea P i astfel:<br />
timp CPU consumat de pi<br />
Pi<br />
<br />
timpdestationare inmemoriealui pi<br />
Se garantează astfel un timp mediu de răspuns, rezonabil pentru fiecare proces din sistem.<br />
În schimb, nu se asigură răspuns prompt la o execuţie preferenţială. Din acest motiv<br />
UNIX nu este un SO în timp real.<br />
Round-Robin( planificare circulară). Aceşti algoritmi sunt destinaţi SO care<br />
lucrează în time-sharing. Pentru realizare se defineşte o cuantă de timp, între 10 şi 100<br />
milisecunde. Coada READY a proceselor este tratată circular alocând procesorul fiecărui<br />
proces pe durata unei cuante.<br />
Algoritmul cu cozi pe mai multe nivele se aplică atunci când lucrările pot fi<br />
clasificate uşor în grupe distincte. De exemplu, la un SO de tip mixt, interactiv şi serial<br />
pot fi create 5 cozi distincte: taskuri sistem, lucrări interactive, lucrări în care se editează<br />
texte, lucrări seriale obişnuite, lucrări seriale ale studenţilor.<br />
2.4.3. Planificarea schimburilor cu memoria<br />
Problemele care se pun în legătură cu gestiunea memoriei şi politicile de schimb<br />
sunt următoarele:<br />
1. Care este cantitatea de memorie alocată? La alocarea pe partiţii se alocă de la<br />
început toată cantitatea cerută( paginare statică); la alocarea paginată fiecare program<br />
consumă cantitatea de memorie de care are nevoie la un moment dat( paginare dinamică).<br />
2. În care dintre locurile libere pe care le-ar putea ocupa programul este plasat<br />
acesta în cazul alocării cu partiţii variabile? Rezolvările acestei probleme sunt cunoscute<br />
sub numele de politici de plasare.<br />
3. Când se face compactarea în cazul alocării cu partiţie variabilă respectiv când<br />
este depusă o pagină virtuală într-una fizică la sistemele cu paginare?<br />
4. Care sunt paginile care vor fi evacuate( swap) în cazul în care toate paginile<br />
fizice sunt ocupate la sistemele cu paginare? Alegerea paginii care va fi înlocuită face<br />
obiectul unor politici de înlocuire( replacement).<br />
Politici de plasare. SO şi multe programe de aplicaţii solicită în timpul execuţiei<br />
lor diverse cantităţi de memorie. Presupunem că întreaga cantitate de memorie solicitată<br />
la un moment dat este formată dintr-un şir de octeţi consecutivi şi că există un rezervor de<br />
memorie( heap în limbajele de programare) de unde se ia această cantitate. Rezolvarea<br />
cererilor presupune existenţa a două rutine: prima are sarcina de a ocupa( aloca) o zonă<br />
de memorie şi de a întoarce adresa ei de început( ex. procedura NEW în Pascal şi funcţia<br />
malloc în „C‟), iar a doua are rolul de a elibera spaţiul ocupat anterior în vederea<br />
refolosirii lui.<br />
Se vor prezenta în continuare câteva metode de organizare a spaţiului de memorie<br />
şi algoritmii de ocupare şi alocare corespunzători. Pe lângă cerinţele de funcţionare, este
- 100 -<br />
bine ca plasarea succesivă a zonelor alocate să împiedice, pe cât posibil fragmentarea<br />
excesivă. Cele mai răspândite metode de plasare sunt:<br />
A. Metoda primei potriviri( First- fit).<br />
B. Metoda celei mai bune potriviri( Best- fit).<br />
C. Metoda celei mai rele potriviri( Worst- fit).<br />
D. Metoda alocării prin camarazi( Budy- system).<br />
Evident că cea mai bună metodă de organizare a spaţiului se face folosind liste<br />
înlănţuite, iar aceste liste să fie păstrate chiar în spaţiul liber. Presupunem că un element<br />
al listei are structura:<br />
type<br />
plista=^lista;<br />
lista= record<br />
lung: integer;<br />
next: plista<br />
end;<br />
const<br />
c= sizeof( lista);<br />
var HEAD: plista;<br />
unde câmpul lung dă lungimea zonei libere; câmpul next este pointer către următorul<br />
element al listei.<br />
Un element al listei se va numi cuvânt de control. Aceste cuvinte vor permite ca<br />
lista zonelor libere să fie înregistrată chiar în aceste zone cu preţul câtorva octeţi la<br />
fiecare zonă. Constanta c dă numărul de octeţi necesari pentru memorarea unui astfel de<br />
cuvânt de control.<br />
Pentru prezentarea unor algoritmi de plasare se fac următoarele convenţii:<br />
- fiecare zonă liberă începe cu un cuvânt de control; câmpul lung al lui indică<br />
numărul de octeţi liberi după cuvântul de control; pointerul next indică următoarea zonă<br />
liberă, punctând la începutul cuvântului ei de control( cuvintele de control vor fi<br />
subliniate cu linii îngroşate în figurile următoare, iar pointerii la zone sunt indicaţi cu<br />
săgeţi)<br />
- fiecare zonă ocupată începe cu un cuvânt de control; câmpul lung al lui indică<br />
numărul de octeţi alocaţi după cuvântul de control( în mod normal acesta coincide cu<br />
numărul de octeţi solicitaţi pentru alocare, în unele situaţii numărul de octeţi alocaţi<br />
depăşeşte cu maximum c numărul de octeţi solicitaţi); zona ocupată este reperată după<br />
cuvântul ei de control<br />
- în algoritmi se va nota cu q pointerul la zona curentă, cu p pointerul la zona<br />
precedentă lui q, cu r pointerul la zona următaore lui q şi( când este cazul) cu s pointerul<br />
la zona următoare lui r.<br />
În figura următoare a) este prezentată o zonă liberă al cărei cuvănt de control<br />
începe la adresa q şi care are l octeţi liberi. Presupunem că se cere alocarea de n octeţi şi<br />
că l>n. Ca rezultat al alocării va apărea una dintre situaţiile b) dacă l-n> c+1 sau c) când<br />
şi ultimii l-n octeţi rămân nefolosiţi.<br />
Înainte<br />
q<br />
a)<br />
r L<br />
L<br />
p<br />
q
- 101 -<br />
După<br />
e<br />
b)<br />
r n<br />
n<br />
r<br />
g<br />
g<br />
p<br />
q+c<br />
n<br />
L-n<br />
r<br />
c)<br />
r L<br />
p<br />
q+c<br />
e= q+ c+ n; g= L- n- c<br />
Procedura de alocare este următoarea:<br />
procedure alocare( var p, q: pointer; n: integer);<br />
var l: integer;<br />
r: pointer;<br />
begin<br />
l:=q^.lung; r:=q^.next;<br />
if l-n>= c+1 then<br />
begin<br />
q^.lung:= n; q:=q+c+n; q^.next:= r;<br />
if p= nil then HEAD:= q<br />
else p^.next:= q;<br />
q:= q- n;<br />
end<br />
else<br />
begin<br />
if p= nil then HEAD:= r<br />
else p^.next:= r;<br />
q:= q+ c<br />
end<br />
end;<br />
Pentru a descrie problema comasării a două zone libere adiacente se va presupune<br />
că lista zonelor libere este păstrată în ordinea crescătoare a adreselor. Situaţia în care este<br />
posibilă comasarea este prezentată în figura următoare:<br />
q L r k<br />
P<br />
L<br />
k<br />
r<br />
t<br />
t= L+ c+ k<br />
t
- 102 -<br />
Algoritmul de comasare a zonei de adresă p cu zona care urmează este:<br />
procedure comasare( var p: pointer);<br />
var<br />
q: pointer;<br />
begin<br />
q:= p^.next; p^.next:= q^.next;<br />
p^.lung:= p^.lung+ c+ q^.lung<br />
end;<br />
Procedura de eliberare a unei partiţii alocate prin procedura de alocare este<br />
următoarea:<br />
procedure eliberare( q: pointer);<br />
var p, r: pointer;<br />
begin<br />
q:= q- c;<br />
if q< HEAD then goto PRIMA;<br />
p:= HEAD; r:= nil; { precedentul lui p}<br />
repeat<br />
if p= nil then goto DUPAULTIMA;<br />
if p^.next> q then goto INTREDOUA;<br />
r:=p; p:= p^.next<br />
until false;<br />
PRIMA: { Zona liberă devine prima din listă}<br />
q^.next:= HEAD;<br />
if q+ c+ q^.lung= HEAD then comasare( q);<br />
HEAD:= q;<br />
goto FINAL;<br />
DUPAULTIMA: { Zona eliberată devine ultima din listă}<br />
r^.next:= q; q^.next:= nil;<br />
if r+ c+ r^.lung= q then comasare( r);<br />
goto FINAL;<br />
INTREDOUA: { Zona e încadrată între alte două zone}<br />
q^.next:= p^.next; p^.next:= q;<br />
if q+ c+ q^.lung= q^.next then comasare( p);<br />
FINAL:<br />
end;<br />
La eliberare partiţia devenită liberă se repune în lista de spaţii libere. De asemenea se<br />
verifică dacă nu cumva partiţia proaspăt eliberată se poate comasa cu una vecină din<br />
dreapta sau stânga ei( în acest fel nu vor există două zone libere adiacente).<br />
Descrierile procedurilor sunt făcute într-un “dialect Pascal”; se ştie că operaţiile<br />
aritmetice asupra pointerilor sunt permise doar în „C‟, deci un progamator bun poate<br />
adapta aceste proceduri astfel încât ele să fie implementate.<br />
În momentul pornirii sistemului se alocă întreaga zonă de memorie sub forma<br />
unei singure zone libere folosind instrucţiunile:<br />
HEAD:= adresa de început a spaţiului de memorie destinat alocării de partiţii;<br />
HEAD^.next:= nil;<br />
HEAD^.lung:= lung max a spaţiului de memorie destinat alocărilor de partiţii;
- 103 -<br />
În procedurile ce descriu primele trei metode se adoptă convenţia că pointerul q<br />
va avea la ieşire adresa de început a celor n octeţi consecutivi solicitaţi pentru alocare.<br />
Dacă nu mai există n octeţi liberi, atunci q va avea la ieşire valoarea nil.<br />
A. Metoda primei potriviri( First- fit). Esenţa acestei metode constă în aceea că<br />
partiţia solicitată este alocată în prima zonă liberă în care încape. Procedura este descrisă<br />
în continuare:<br />
procedure First-fit( n: integer; var q: pointer);<br />
var p: pointer;<br />
begin<br />
p:= nil; q:= HEAD;<br />
repeat<br />
if q nil then<br />
begin<br />
if q^.lung>= n then<br />
begin<br />
alocare( p, q, n); goto IEşIRE<br />
end;<br />
p:= q; q:= q^.next<br />
end<br />
until q= nil;<br />
IEşIRE:<br />
end;<br />
Avantajul acestei metode constă în simplitatea căutării spaţiului liber.<br />
B. Metoda celei mai bune potriviri( Best- fit). Esenţa metodei constă în căutarea<br />
acelei zone libere care lasă după alocare cel mai puţin spaţiu liber. Descrierea metodei<br />
este următoarea:<br />
procedure Best-fit( n: integer; var q: pointer);<br />
var p,r,s: pointer; x: integer;<br />
begin<br />
r:= nil; s:= HEAD; x:= maxint;<br />
while s nil do<br />
begin<br />
if ( s^.lung>= n) and ( x> s^.lung- n) then<br />
begin<br />
x:= s^.lung- n; p:= r; q:= s<br />
end;<br />
s:= s^.next<br />
end;<br />
if x< maxint then alocare( p, q, n)<br />
end;<br />
Avantajul acestei metode este că economiseşte zonele de memorie mai mari.<br />
Există însă şi două dezavantaje: timpul suplimentar de căutare şi fragmentare internă<br />
excesivă. Pentru înlăturarea neajunsurilor se pot păstra spaţiile libere în ordinea<br />
crescătoare a lungimilor şi nu a adreselor.
- 104 -<br />
C. Metoda celei mai rele potriviri( Worst- fit). În esentţa, această metodă eset<br />
duala metodei celei mai bune potriviri şi constă în căutarea acelei zone care lasă cel mai<br />
mult loc liber după alocare. Descrierea metodei este următoarea:<br />
procedure Worst-fit( n: integer; var q: pointer);<br />
var p,r,s: pointer; x: integer;<br />
begin<br />
r:= nil; s:= HEAD; x:= -1;<br />
while s nil do<br />
begin<br />
if ( s^.lung>= n) and ( x< s^.lung- n) then<br />
begin<br />
x:= s^.lung- n; p:= r; q:= s<br />
end;<br />
s:= s^.next<br />
end;<br />
if x -1 then alocare( p, q, n)<br />
end;<br />
Faptul că după alocare rămâne un spaţiu liber mare este benefic deoarece în<br />
spaţiul rămas poate fi plasată o altă partiţie.<br />
D. Metoda alocării prin camarazi( Buddy- system). Această metodă<br />
exploatează reprezentarea binară a adreselor şi faptul că dimensiunea memoriei interne<br />
este multiplu de 2. Fie c2 n dimensiunea memorie interne. Se notează cu n cea mai mare<br />
putere a lui 2 prin care se poate exprima dimensiunea memoriei interne. Se stabileşte ca<br />
unitate de alocare a memoriei tot o putere a lui 2.<br />
La sistemele Buddy dimensiunile spaţiilor ocupate şi a celor libere sunt de forma<br />
2 k cu m<br />
k n. Ideea este de a păstra liste separate de spaţii disponibile pentru fiecare<br />
dimensiune 2 k din cele de mai sus. Vor exista astfel n-m+1 liste de spaţii disponibile.<br />
Prin definiţie, fiecare spaţiu liber sau ocupat de dimensiune 2 k are adresa de început un<br />
multiplu de 2 k . Două spaţii libere de ordinul k se numesc camarazi( Buddy) de ordin k<br />
dacă adresele lor A 1 şi A 2 verifică:<br />
k<br />
k+1<br />
A1 A2 , A2 A1 2 si A1<br />
mod 2 = 0<br />
k<br />
k+1<br />
sau A2 A1 , A1 A2 2 si A2<br />
mod 2 = 0 .<br />
Atunci când într-o listă de ordin k apar doi camarazi, sistemul îi concatenează într-un<br />
spaţiu de dimensiune 2 k 1 .<br />
Alocarea în sistem Buddy se desfăşoară astfel:<br />
1. Se determină cel mai mic număr p, cu m p n pentru care numărul o de<br />
p<br />
octeţi solicitaţi verifică o 2 .<br />
2. Se caută, în această ordine, în listele de ordin p, p+1, p+2, ..., n o zonă liberă<br />
de dimensiune cel puţin o.<br />
3. Dacă se găseşte o zonă de ordin p atunci aceasta este alocată şi se şterge din<br />
lista de ordin p.<br />
4. Dacă se găseşte o zonă de ordin k> p atunci se alocă primii 2 p octeţi, se şterge<br />
p p zona din lista de ordin k şi se creează k- p zone libere cu dimensiunile 2 2 1 k<br />
, ,..., 2<br />
1 .
- 105 -<br />
Eliberarea într-un sistem Buddy a unei zone de dimensiune 2 p este un proces<br />
invers alocării şi se desfăşoară astfel:<br />
1. Se introduce zona respectivă în lista de dimensiune p.<br />
2. Se verifică dacă zona eliberată are un camarad de ordin p. Dacă da, atunci zona<br />
este comasată cu acest camarad şi formează împreună o zonă liberă de dimensiune 2 p 1 .<br />
Atât zona eliberată cât şi camaradul său se şterg din lista de ordin p, iar zona nou apărută<br />
se adaugă la lista de ordin p+1.<br />
3. Se execută pasul 2 în mod repetat mărind p cu o unitate până când nu se mai<br />
pot face comasări.<br />
Avantajul acestei metode este manipularea comodă a adreselor de zone( adresele<br />
a doi camarazi de ordin k diferă doar prin bitul de pe poziţia k).<br />
Politici de încărcare. La sistemele cu alocare paginată, în momentul lansării în<br />
execuţie a programului acesta nu are nici o pagină în memorie. La prima solicitare a<br />
programului SO îi aduce în memorie numai pagina solicitată. Programul funcţionează<br />
normal un timp, după care va cere o nouă pagină care nu este în memorie. Problema care<br />
apare este reducerea numărului de cereri de aducere a paginilor în memorie.<br />
O soluţie simplă, dar ineficientă este aducerea de la început în memorie a tuturor<br />
paginilor( dispare mecanismul de paginare).<br />
O altă modalitate este aducerea de pagini la cerere( în mometul solicitării ei).<br />
Această metodă este frecvent utilizată.<br />
Există metode prin care se aduc în memorie pagini în avans. Astfel, odată cu o<br />
pagină se aduc în memorie şi câteva pagini vecine, în ipoteza că acestea vor fi invocate în<br />
viitorul apropiat. Legat de încărcarea în avans, P.J. Denning a emis principiul vecinătăţii:<br />
adresele de memorie solicitate de un program nu se distribuie uniform pe întreaga<br />
memorie folosită, ci se grupează în jurul unor centre. Apelurile în apropierea acestor<br />
centre sunt mult mai frecvente decât apelurile de la un centru la altul. Acest principiu<br />
sugerează o politică de încărcare în avans a unor pagini după cum urmează: se stabileşte<br />
o memorie de lucru compusă din câteva pagini; în momentul solicitării unei pagini de pe<br />
disc se aduc în memoria de lucru şi câteva pagini vecine. În conformitate cu principiul<br />
vecinătăţii este probabil ca următoarele referiri să fie făcute în cadrul memorie de lucru.<br />
Politici de înlocuire. Numărul total al paginilor active poate deveni mai mare<br />
decât numărul paginilor fizice din memorie operativă. Se pune întrebarea care dintre<br />
paginile paginile fizice să fie evacuată pentru a crea spaţiul necesar? Optim ar fi să fie<br />
evacuată pagina care va fi solicitată cel mai târziu, acest lucru este însă imposibil de<br />
realizat. Dintre metodele mai obişnuite se folosesc în special trei:<br />
- înlocuirea unei pagini care nu a fost recent utilizată( NRU, Not Recently Used).<br />
În acest caz se împart paginile fizice, cu ajutorul a doi biţi în patru clase: clasa 0- pagini<br />
nereferite şi nemodificate, 1- pagini nereferite, dar modificate la încărcare, 2- pagini<br />
referite , dar nemodificate, 3- pagini referite şi modificate. Când o pagină trebuie<br />
înlocuită se începe alegerea ei cu clasa 0 ş.a.m.d.<br />
- înlocuirea în ordinea încărcării paginilor( FIFO, First In First Out). Pentru a<br />
realiza acest lucru se creează şi actualizează o listă a paginilor în ordinea încărcării lor.<br />
- înlocuirea paginii nesolicitate cel mai mult timp( LRU Least Recently Used).<br />
Acest mod de înlocuire se bazează pe observaţia că o pagină care a fost mai mult utilizată<br />
de către ultimele instrucţiuni, va fi probabil solicitată mai des şi în continuare.