Sunteți pe pagina 1din 27

SISTEME DE OPERARE

Alexandru Averian
http://www.yonan.ro

Bibliografie obligatorie ...................................................................................................................... 1


Definiţii. Clasificări. Exemple ............................................................................................................ 2
Clasificare.......................................................................................................................................... 3
Arhitectura hardware a unui sistem de calcul .................................................................................... 4
Sistemul de intreruperi .................................................................................................................. 4
Apeluri sistem................................................................................................................................ 6
Drivere de dispozitiv ...................................................................................................................... 7
Structura unui sistem de operare ...................................................................................................... 9
Componentele unui SO.................................................................................................................... 11
Managementul proceselor .............................................................................................................. 15
Managementul procesorului ( Scheduling )...................................................................................... 17
Criterii de planificare: .................................................................................................................. 17
Algoritmi de planificare ............................................................................................................... 17
Managementul memoriei ................................................................................................................ 19
Metode clasice de alocare a memoriei ......................................................................................... 19
Managementul fişierelor ................................................................................................................. 26
Bibliografie ...................................................................................................................................... 27

Bibliografie obligatorie
• Silberschatz A., Galvin P.B. and Gagne G. (2005). Operating Systems Concepts, 7th edn.
John Wiley & Sons
• Tanenbaum A.S. (1987). Operating Systems, Design and Implementation. Englewood
Cliffs NJ: Prentice-Hall.
• Tanenbaum A.S. (1992). Modern Operating Systems. Englewood Cliffs NJ: Prentice-Hall.
Definiţii. Clasificări. Exemple

Un sistem de calcul este alcătuit dintr-un ansamblu de componente hardware, software şi


resurse informaţionale. Din punct de vedere hardware un sistem de calcul este compus din
procesoare, magistrale, memorie internă, discuri, diverse dispozitive de intrare/ieşire cum
ar fi tastatura, display, imprimata, scaner, adaptoare de retea, etc. Dezvoltarea de programe
care să utilizeze direct componentele hardware ale unui sistem este o sarcină extrem de
dificilă deoarece aceste componente se regăsesc într-o mare varietate de modele
constructive şi gestionarea optimă a acestora devine practic imposibilă. În plus, autorul unui
program ce realizează calcule ştiinţifice sau economice nu trebuie să fie preocupat de modul
intern de funcţionare al discurilor, tastaturii sau imprimantei.
Apare astfel nevoia unui sitem de operare (SO) numit şi program de bază care să gestioneze
corect şi eficient componentele hardware ale unui calculator să izoleze utilizatorul de
hardware şi să ofere programatorilor de aplicaţii şi utilizatorilor un sistem generic cu
funcţionalitate extinsă, uşor de programat.
Sistemul de operare (numit şi software de bază) reprezintă o colecţie de programe încărcate
în memorie la pornirea unui sistem de calcul, având următoarele funcţii principale:
• Funcţia de administrare a resurselor hardware, software şi a informaţiilor
• Funcţia de abstractizare şi de extindere a funcţionalităţii sistemului de calcul.
D.p.d.v. al maşinii sistemul de operare (S.O.) are funcţia de administrare a resurselor
hardware, funcţie exercitată prin controlil alocării către programe a resurselor hardware
partajate, cum ar fi procesor, memorie, discuri şi dispozitive de Intrare/ Ieşire.
D.p.d.v. al programatorului de aplicaţii şi al utilizatorului S.O. are rolul de a reduce
complexitatea utilizării directe a maşinii fizice. Funcţia de abstractizare şi de extindere a
funcţionalităţii se realizează prin ascunderea structurii interne a componentelor maşinii şi
prin încapsularea operaţiilor primitive cu acestea în module speciale ale S.O. numite drivere.
S.O. creează astfel iluzia( imaginea) unei maşini virtulale cu o funcţionalitate extinsă, având
o interfaţă de lucru simplificată, cu funcţii de nivel înalt mai uşor de utilizat în programare.
S.O. este format dintr-un set de programe. Partea principală a unui S.O. (miezul) se încarcă
în memorie la pornirea caculatorului, rămâne rezidentă în memorie şi are rol de supervizor.
Miezul S.O. se află într-un fişier şi se numeşte kernel. Fişierul se numeşte imaginea
kernelului.
Funcţiile principale ale unui S.O. aflate în kernel sunt legate de:
• gestiunea proceselor
• gestiunea procesorului
• comunicarea între procese, sincronizare
• gestiunea memoriei
• gestiunea operaţiilor legate de întreruperi
• gestiunea fişierelor
Clasificare
S.O. au apărut şi au evoluat odată cu evoluţia sistemelor de calcul.
1. Calculatoare mainframe:
• calculatorul era programat direct
• nu existau sisteme de operare
• in memorie rula cel mult un program
• odată cu apariţia tranzistoarelor: apare primul limbaj de programare şi primul
S.O. care utiliza conceptul de procesare pe loturi( batch-jobs) şi conceptul de job.
Procesorul era slab utilizat deoarece perifericele aveau viteză foarte scăzută;
apare multiprogramarea pentru a ţine procesorul ocupat in mod otim. În
memorie se încarcă mai multe programe iar planificatorul alege unul din acestea.

2. Sisteme interactive (cu partajarea timpului):


• permit interacţiunea utilizatorului cu programele care rulează în memorie
• apare noţiunea de multitasking care reprezintă o extensie a multiprogramării şi în
care comutarea între programe se realizează atât de rapid încât utilizatorul are
senzaţia că se execută mai multe programe simultam.
3. Sisteme Desktop
4. Sisteme de tip real
5. Sisteme încorporate
6. Sisteme cu multiprocesor
7. Sisteme distribuite
8. Clustere
9. Reţele peer-to-peer
10. Reţele client server

Exemple: FreeBSD, Linux, Unix, Solaris, Plan9, Windows, MsDos, Symbian


Arhitectura hardware a unui sistem de
calcul
Datorita multitudinii si diversitatii sarcinilor pe care le are de indeplinit, sistemul de operare
nu poate fi conceput sub forma unui program unitar. Practic, sistemul de operare consta
dintr-o multime de secvente de program, fiecare indeplinind o anumita sarcina.

Un argument in favoarea unei asemenea abordari, in afara considerentelor de fiabilitate si


usurinta in dezvoltare, il constituie evolutia continua a tehnologiilor utilizate, in special in
ceea ce priveste dispozitivele periferice. Daca la un moment dat se pune problema inlocuirii
intr-un calculator a unui asemenea periferic (de exemplu mouse) cu unul mai nou, va trebui
schimbata secventa de program care se ocupa de gestionarea sa. In cazul in care sistemul de
operare ar fi un program unic, acesta ar trebui inlocuit in intregime, ceea ce este
inacceptabil in practica. Asupra acestui aspect vom reveni ulterior.

Pe de alta parte, exista o serie de operatiuni fundamentale, care trebuie realizate


intotdeauna in acelasi mod, independent de particularitatile hardware-ului. Partile de
program care indeplinesc aceste sarcini fundamentale formeaza nucleul sistemului de
operare, care dirijeaza si controleaza functionarea sistemului de calcul in ansamblul sau. In
continuare, notiunile de sistem de operare si de nucleu al sistemului de operare se vor
confunda in mare masura, deoarece celelalte componente ale sistemului de operare sunt
utilizate de catre nucleu pentru a-si indeplini sarcinile.

Nu exista intotdeauna o delimitare clara intre nucleu si celelalte componente. Conceptiile


diversilor producatori de sisteme de operare difera in ceea ce priveste locul unora dintre
functii - in nucleu sau in afara sa. Totusi, practic toate sistemele de operare existente includ
in nucleu urmatoarele componente:

• gestiunea proceselor
• gestiunea memoriei
• sistemele de fisiere

Majoritatea activitatilor pe care le desfasoara sistemul de operare nu pot fi realizate exclusiv


prin software. Este necesar un sprijin, uneori substantial, din partea componentelor
hardware si in special din partea procesorului. Natura exacta a acestui sprijin va fi discutata
in continuare.

Sistemul de intreruperi

Principala facilitate oferita de catre procesor o constituie sistemul de intreruperi.


Necesitatea acestuia devine evidenta in momentul in care studiem modul in care se executa
programele. Uzual, procesorul executa instructiunile intr-o ordine data de urmatoarele
reguli:
• daca instructiunea curenta este una de salt, va fi executata in continuare
instructiunea de la adresa la care se face saltul
• in caz contrar, va fi executata in continuare instructiunea aflata in memorie la adresa
imediat urmatoare dupa instructiunea curenta

Ca o concluzie generala, intotdeauna o instructiune care face parte dintr-un program va fi


urmata de o alta instructiune din acelasi program. Pana aici nu exista nici o posibilitate de a
parasi programul aflat in executie decat daca acesta se termina singur. Acest model
corespunde in general cerintelor, deoarece un program aflat in executie ruleaza in
majoritatea timpului fara a tine cont de existenta sistemului de operare; totusi, acesta din
urma trebuie sa poata interveni in anumite situatii bine definite, cum ar fi:

• incercarea unui program de a efectua o actiune nepermisa


• o cerere explicita adresata de programul de aplicatie, privind efectuarea unui anumit
serviciu de catre sistemul de operare
• alte evenimente aparute in sistem, care pot sa nu aiba legatura cu programul aflat in
executie, dar care trebuie tratate imediat

Sistemul de operare va lasa deci orice program sa se execute fara interferente pana la
aparitia uneia din situatiile descrise mai sus, dar in acest moment trebuie sa preia imediat
controlul. Solutia este, asa cum am precizat deja, de natura hardware si este reprezentata
de sistemul de intreruperi. Concret, acesta ofera tocmai posibilitatea intreruperii executiei
programului curent in una din urmatoarele situatii:

• o cerere de intrerupere venita din partea unui dispozitiv periferic; acest caz poarta
denumirea de intrerupere hardware
• o operatie executata de procesor, care a dat un rezultat anormal (de exemplu o
operatie de impartire la 0); asemenea situatii sunt denumite exceptii
• o cerere explicita venita chiar din partea programului aflat in curs de executie;
asemenea cereri, numite intreruperi software, sunt utilizate de obicei pentru a cere
sistemului de operare efectuarea unui anumit serviciu pe care programul de aplicatie
nu-l poate realiza singur

Indiferent care este cauza care a produs intreruperea, comportarea procesorului este
urmatoarea:

• executia programului curent este suspendata si se memoreaza informatiile necesare


pentru a putea relua in viitor executia respectivului program, fara a-i fi afectata
comportarea
• se identifica sursa cererii de intrerupere
• in functie de cauza intreruperii, se apeleaza o anumita rutina care este responsabila
de tratarea respectivei situatii
• la terminarea rutinei, folosind informatiile memorate, se revine la executia
programului intrerupt, exact in punctul in care se afla acesta in momentul
intreruperii
Evident, rutinele care trateaza situatiile generatoare de intreruperi fac parte din sistemul de
operare, care poate astfel rezolva problemele aparute. Datorita flexibilitatii sale,
mecanismul intreruperilor este folosit astazi de toate procesoarele existente. Asa cum vom
vedea in continuare, acest mecanism sta la baza multor facilitati oferite de sistemele de
operare.

Apeluri sistem

Una din sursele intreruperilor, prezentate mai sus, o constituie solicitarile formulate in mod
explicit de programele de aplicatii catre sistemul de operare, pentru efectuarea anumitor
servicii. De ce este insa necesar ca aceste servicii sa fie implementate de catre sistemul de
operare si nu pot fi lasate in seama programelor? In primul rand, unele operatii uzuale
(afisarea, cautarea pe disc etc.) se desfasoara intotdeauna in acelasi mod; deci, in loc de a
scrie practic aceeasi rutina in fiecare program, este mai economic de a o scrie o singura data
ca parte a sistemului de operare, astfel ca toate aplicatiile sa o poata utiliza.

Pe de alta parte, o serie de actiuni, in special accesele la dispozitivele periferice, prezinta


riscuri considerabile pentru intregul sistem de calcul in cazul in care nu sunt realizate corect.
Nu este deci convenabil de a permite programelor de aplicatie sa realizeze singure actiunile
din aceasta categorie; se prefera ca activitatile de acest tip sa fie indeplinite numai prin
intermediul unor rutine incluse in sistemul de operare. Pentru a pune in practica o
asemenea abordare, trebuie sa se poata interzice pur si simplu realizarea anumitor operatii
de catre programele de aplicatii. Din nou este necesar un suport hardware. Practic toate
procesoarele existente astazi pot functiona in doua moduri distincte:

• modul utilizator (user mode), in care exista anumite restrictii pentru procesor, in
principal nu se pot executa instructiunile de acces la periferice (incercarea de a
executa o asemenea instructiune duce la generarea unei exceptii)
• modul supervizor sau nucleu (kernel mode), in care procesorul nu are nici o limitare

In mod uzual, programele de aplicatii se executa in mod utilizator, iar sistemul de operare
ruleaza in mod nucleu. In acest fel se asigura controlul sistemului de operare asupra
operatiilor critice. Desi aplicatiile pierd din performanta prin limitarile impuse de modul
utilizator, cresterea stabilitatii in functionare justifica din plin aceasta abordare. In acest
moment putem studia ce se intampla atunci cand un program cere sistemului de operare
furnizarea unui anumit serviciu. O asemenea cerere poarta numele de apel sistem (system
call) si consta din urmatorii pasi:

• programul, care ruleaza in modul utilizator al procesorului, depune parametrii


apelului sistem pe care il solicita intr-o anumita zona de memorie; practic,
mecanismul este similar apelurilor de proceduri
• se executa o instructiune speciala (in general o intrerupere software), care trece
procesorul in modul nucleu
• se salveaza (in general pe stiva) informatiile legate de programul intrerupt care sunt
necesare pentru reluarea ulterioara a executiei sale din acelasi punct
• se identifica serviciul cerut si se apeleaza rutina corespunzatoare
• rutina respectiva preia parametrii apelului din zona in care au fost depusi, ii verifica
si, daca nu sunt erori, realizeaza actiunea ceruta; rezultatele obtinute sunt la randul
lor depuse intr-o zona de memorie cunoscuta programului de aplicatie
• la terminarea rutinei, procesorul revine in mod utilizator si se reia executia
programului din punctul in care a fost intrerupt (utilizand informatiile memorate
anterior in acest scop); programul poate prelua rezultatele apelului din zona in care
au fost depuse

Se poate observa ca executia unui apel sistem este mare consumatoare de timp. Din fericire,
puterea de calcul a procesoarelor moderne este suficient de mare incat sa reduca in limite
acceptabile pierderea de performanta datorata apelurilor sistem, iar cresterea fiabilitatii
sistemului de calcul in ansamblul sau justifica din plin aceasta abordare. Totusi, pentru
aplicatiile in care performanta este critica, se cauta solutii de reducere a ponderii apelurilor
sistem, pentru a micsora intarzierile produse de acestea. Unele dintre aceste solutii tin de
insasi structura sistemului de operare si vor fi discutate mai tarziu. Exista insa o solutie aflata
la indemana programatorilor de aplicatii - lucrul cu buffere.

Esenta acestei idei este urmatoarea: pentru majoritatea perifericelor, o mare parte din
timpul de comunicare se datoreaza initierii accesului si nu transferului propriu-zis de date.
Rezulta de aici ca s-ar putea economisi timp daca ar fi servite mai multe asemenea cereri
intr-un singur acces, in loc de a le servi pe fiecare intr-un acces separat. In mod particular
accesul la disc are aceasta caracteristica foarte pronuntata. Solutia este deci de a nu incerca
servirea imediata a fiecarei cereri de transfer de date cu un periferic, ci de a astepta
acumularea mai multor cereri si a le servi pe toate intr-un singur acces. In acest scop,
cererile care asteapta sa fie servite trebuie memorate intr-o zona de memorie dedicata,
numita buffer.

Ca un exemplu, consideram sistemele din familia Unix, in care aplicatiile sunt scrise in mod
traditional in limbajul C. Functia de biblioteca printf se bazeaza pe apelul sistem write, care
realizeaza afisarea propriu-zisa. La fiecare apel al functiei printf, sirul de caractere care se
doreste a fi afisat este depus intr-un buffer; in plus se verifica daca bufferul s-a umplut, caz
in care este realizat un apel sistem write, ce afiseaza toate sirurile din buffer. In acest mod
se obtine un castig de viteza care in unele cazuri poate fi substantial.

In multe situatii sistemul de operare foloseste el insusi buffere. In general insa apelurile
sistem lucreaza fara buffere, deoarece in unele cazuri aplicatia poate avea nevoie ca un
anumit transfer sa fie efectuat cat mai repede posibil, fara a mai astepta sosirea altor cereri
care sa umple bufferul. Modul de lucrul cu buffere poate fi implementat la nivelul functiilor
de biblioteca sau chiar direct de catre utilizator.

Drivere de dispozitiv

Asa cum s-a aratat deja, gestionarea dispozitivelor periferice se confrunta cu desele
schimbari suferite de acestea, ca urmare a progresului tehnologic rapid. Este practic
imposibil ca producatorul unui sistem de operare sa poata scrie secventele de program
necesare pentru gestionarea tuturor perifericelor existente pe piata, cu atat mai mult cu cat
permanent apar noi modele. Situatia este valabila in principal pentru imprimante, dar si
pentru celelalte tipuri de periferice (placi video, unitati CD, mouse, placi de retea, placi
audio, chipset-urile placilor de baza etc.), cu exceptia partiala a tastaturilor si a discurilor
hard, unde maturitatea tehnologica a condus la o standardizare puternica. Din acest motiv
se prefera ca gestionarea perifericelor sa fie lasata in seama unor module de program,
numite drivere, exterioare nucleului, dar care pot coopera cu acesta. Pentru fiecare
dispozitiv periferic existent intr-un calculator trebuie sa existe un driver, altfel respectivul
periferic nu va putea fi folosit. In general sistemele de operare contin drivere pentru
modelele de periferice cele mai utilizate; in cazul celorlalte, driverele trebuie furnizate de
producatorii respectivelor dispozitive.

Utilitatea mecanismului driverelor este evidenta: permite schimbarea usoara a oricarui


periferic, fara a fi necesara reinstalarea intregului sistem de operare. De asemenea,
depistarea si corectarea erorilor devine mult mai facila. Cu toate acestea, in mod traditional,
sistemele de operare din familia Unix au o abordare mai putin flexibila, incluzand driverele
in nucleu. Aceasta atitudine se justifica prin faptul ca, pentru majoritatea sistemelor Unix,
producatorul este si singurul ofertant de hardware, deci nu trebuie sa faca fata unui numar
mare de dispozitive produse de alte firme. Totusi, sistemul Linux si alte sisteme Unix ofera in
ultima vreme suport pentru incarcarea dinamica a unor module.
Structura unui sistem de operare
Monolitic:
• kernelul format dintr-un fişier;
• majoritatea fişierelor se află în kernel;
• este o colecţie de funcţii fără nicio ierarhizare internă;
Modular :
• sistemul este stucturat pe module cu functionalitati bine precizate

Stratificat:
• este compus din straturi suprapuse, fiecare strat oferind servicii stratului
superior şi abstractizând structura şi operaţiile cu operaţiile stratului inferior;

Exokernel:
• majoritatea serviciilor sunt în afara kernelului şi ruleaza în user-mode;
• kernelul păstrează funcţiile de comunicare între procese şi de izolare;
• se mai numeşte kernel la purtător;
• creează maşinivirtuale,cărora le alocă resurse, fiecare maşină virtuală rulând
propriul S.O. şi propriile procese;
Maşina virtuală:
• similar cu exokernelul, cu deosebirea ca maşinile virtulesunt copii ale hardului pe
care rulează, având propria copie a kernelului şi întreruperi proprii:
• pot rula S.O. diferite;
Sisteme client-server:
( microkernel)
• majoritatea serviciilor ruleaza in user-mode, kernelul asigurâd comunicaţia şi
sincronizareaîntre procesele client şi server;
• exemple server: fişiere, memorie,terminale;
Sisteme distribuite:
• similar cu client-server, cu deosebirea că serverul şi clientul pot fi pe maşini
diferite;
Exemple:

• MSDOS – monolitic, nestructurat


• Windows XP – arhitectura stratificată
• BSD Unix , Solaris – arhitectura modulară
• True 64 UNIX, QNX - mikrokernel
• Linux – artitectura monolitica
• Mach – microkernel
• Mac OS X – stratificat, modular
• Minix – microkernel
Componentele unui SO
1. Componenta de management a memoriei:

Procesul citeşte instrucţiuni, citeşte si scrie date din memorie. Perifericele controlate prin
mecanismul DMA citesc si scriu date în memorie. Programele sunt încărcate de pe disk în
memorie. Dacă un program se executa, acesta citeşte instrucţiunile si datele din memorie,
accesâd memoria prin adresele de memorie reprezentate pe 16, 32 sau 64 de biţi. Odată
terminat un program, el este eliberat din memorie si spaţiul său este alocat altui program.
Pentru a îmbunătăţii utilizarea CPU si pentru a mări viteza de reacţie a sistemului faţă de
utilizatori sistemul de operare trebuie sa ţină în memorie mai multe programe în acelaşi
timp (multiprogramare). Există mai multe scheme de management a memoriei, selectarea
unei anumite scheme pentru un S.O. depinzând de mai mulţi factori, în special de platforma
hardware a sistemului destinaţie. Sistemul de operare asigură următoarele operaţii în ceea
ce priveşte managementul memoriei:
• alocă si dezalocă memorie la cerere;
• menţine o situaţie a memoriei alocate şi a memoriei libere.
• decide ce proces să fie încărcat în memorie când aceasta devine disponibilă
2. Managementul proceselor:

Sistemul de operare este responsabil cu gestiunea proceselor. Modulul (componenta) unui


Sistem de Operare care gestionează procesele trebuie sa asigure următoarele funcţii:
• funcţii de creare a unui proces (user sau proces de sistem);
• ştergerea sau eliberarea uni proces din memorie;
• să asigure mecanisme de sincronizare a proceselor;
• să asigure mecanisme de comunicare între procese;
• să asigure mecanisme de gestionare a interblocărilor.

• creează şi eliberează procese;


• suspendă şi reia executarea proceselor;
• asigură mecanismele de comunicare şi sincronizare între procese;
• se ocupă de evitarea interblocaţiilor;
3. Planificarea procesorului:
• asigură accesul proceselor la resursa procesor într-un mod echitabil;
• utilizează algoritmi de planificare pentru a împarţi timpul de lucru al procesorului
între procesele din memorie;
4. Gestiunea fişierelor
5. Gestiunea componentelor de Intrare/Ieşire:
• gestionează perifericele;
• asigură alocarea corectă a acestora către procese;
• controlează operaţiile de Intrare/Ieşire.

6. Managementul dispozitivelor de stocare


Asigură:

• managementul spaţiului liber ;


• alocarea spaţiului la cerere;
• planificarea şi controlul accesului la discuri.

7. Componenta de reţea
8. Sistemul de protecţie
9. Interfaţa de programare a aplicaţiilor(API):
• oferă programatorului un set de funcţii de nivel înalt prin care acesta poate
accesa în programare serviciile oferite de celelalte componente ale S.O.
Serviciile sunt oferite către utlizatorul programtor:
• încărcarea şi executarea programelor
• operaţii (servicii) de I/O.
• manipularea sistemelor de fişiere (creare, ştergere, scriere şi citire).
• comunicaţii între procese (prin memorie partajată sau prin transfer direct de
mesaje între procese);
• detectarea erorilor şi recuperare după eroare (eroare de CPU, de memorie, de
scriere, citire, de reţea, imprimantă).
Sistemul de operare permite accesul la serviciile sale prin apelul unor funcţii ale
sistemului denumite apeluri-sistem. Aceste apeluri alcătuiesc interfaţa de acces a
programatorului către serviciile sistemului de operare. Aceste funcţii pot fi apelate direct în
limbaj de ascultare prin intermediul vectorului de întreruperi sau în limbaj de nivel înalt prin
apelul unor funcţii de biblioteca (care la rândul lor invoca serviciile sistemului, generând
întreruperile necesare). In sistemul MS-DOS apelul la serviciile S.O. se realizau prin
intermediul întreruperii 21H. In Unix şi în Linux se accesează prin întreruperea 80H. Printre
serviciile sistemului enumerăm:

• write, create, read/delete, fork, exec, wait, load


• free, create, delete, send, receive
Exemplu
10. Terminalul( interfaţa grafică):
• oferă posibilitatea utilizatorului calculatorului de a interacţiona cu sistemul de
calcul prin lansarea de procese;
Exemplu de shell
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/wait.h>

#define MAXLINE 256

int main(void)
{
char buf[MAXLINE];
pid_t pid;
int status;

printf("%% ");
while (fgets(buf, MAXLINE, stdin) != NULL)
{
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
if ((pid = fork()) < 0) {
printf("fork error");
}
else if (pid == 0)
{
/* child */
execlp(buf, buf, (char *)0);
printf("couldn't execute: %s", buf);
exit(127);
}

/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
printf("waitpid error");
printf("%% ");
}
return 0;
}

În plus, un sistem multiuser trebuie să asigure următoarele servicii:

• alocarea resurselor;
• conturi pentru utilizatori;
• protecţia informaţiei;
• securitatea sistemului faţă de interior.
Managementul proceselor
Un proces este o unitate de lucru în cadrul unui sistem de calcul care are un program
asociat, căruia i se alocă un set de resurse de memorie, de procesor,etc. şi care execută în
mod secvenţial instrucţiunile programului.

Procesul se mai numeşte şi joburi, mai ales în contextul planificării proceselor. La lansarea
unui proces, acestuia i se alocă o zonă de memorie pentru stivă, o zonă pentr date şi o zonă
de memorie heap care e alocată dinamic la rulare. In plus, procesul mai conţine un contor
de program numit instruction pointer şi conţinutul registrelor procesorului.

Procesul se poate afla în una din următoarele stări:

• proces nou
• rulează
• asteaptă
• gata
• terminat

Informaţia legată de stare face parte din datele asociate fiecărui proces. Aceste informaţii
despre un proces sunt cnţinute de către planificatorul de procese într-o structură specială
numită Process Control Block.

O structură PCB conţine:

• Starea procesului
• I.D. procesului
• Instruction pointer(IP)
• Registele procesorului
• Memoria alocată
• Fişiere deschise
• Informaţii de planificare( prioritate)
• Lista de dispozitive de Intrare/Ieşire asociată procesului

Un proces nu este un program. In modelul de proces discutat până acum, programul asociat
era executat secvenţial, instrucţiune după instrucţiune. Altfel spus,un singur proces execută
o singură operaţiune la un moment dat. Sunt cazuri în care se doreşte ca un program să
execute în paralel două sau mai multe operaţii. Altfel spus, să execute mai multe proceduri
din program In acelaşi timp. Acest lucru se obţine prin introducerea în proces a mai multor
fire de execuţie.

Avantaje:

• Aplicaţiile răspund mai ferm la interacţiunea cu utilizatorul


• Permit partajarea resurselor
• Duc la economia de memorie şi de procesor
• Utilizarea optimă a calculatoarelor multiprocesor

Firele pot fi gestionate la nivel de user-mode sau la nivel de kernel. S.O. moderne oferă
suport pentru fire la nivel de kernel.Există mai multe modele de implementare a firelor:

• Many-to-One Model: mai multe fire dintr-un p[roces sunt gestionate ( reprezentate )
de un singur fir din kernel. Comutarea între fire este rapidă şi este gestionată în
spaţiul utilizator. Dar toate firele se blochează în cazul în care unul din fire este
blocat într-un apel de sistem. De asemenea, deoarece un singur fir poate accesa
kernelul, acest model de fire nu poate permite rularea în paralel a firelor pe mai
multe procesoare.
• One-to-One Model: fiecărui fir din spaţiul user-mode îi corespunde un fir în kernel.
Dezavantajul este că pentru fiecare fir se mai creează încă unul în kernel. Linux,
Windows, Unix implementează acest model.
• Many-to-Many Model: mai multe fire din kernel folosesc la planificarea mai multor
fire din spaţiul utilizator. Programatorii pot crea oricât de multe fire în programele
lor.
• Model hibrid (many to many plus one to one)
Managementul procesorului ( Scheduling )
In sistemele multiprogramate, în memorie sunt încărcate mai multe programe la un
moment dat. S-a observat că unele procese sunt mai mult procese de calcul, iar altele
manipulează date prin sistemul Intrare/Ieşire, iar în cadrul unui proces s-a observat
repetarea ciclică a unei faze de calcul intens urmată de o fază de aşteptare la periferice de
Intrare/Ieşire. Deci procesul execută o rafală de instrucţiuni pe procesor, după care aşteaptă
sosirea datelor la dispozitivul de Intrare/Ieşire.

Intre două rafale de instrucţiuni procesorul nu este utilizat. Pentru o utilizare optimă a lui,
acesta poate fi cedat unui alt proces care îşi va executa rafala de instrucţiuni până la prima
fază de aşteptare a datelor.

Planificarea accesului la procesor de către procese foloseşte algoritmul de planificare.

Exista două tipuri de algoritmi de planificare:

• Algoritmi preemptivi: procesul curent poate fi întrerupt oricănd de către S.O. ( dacă îi
expiră cuanta de timp)
• Algoritmi nepreemptivi: procesul nu poate fi întrerupt oricănd de către S.O.; acesta
cedează controlul de bunăvoie la terminarea rafalei de instrucţiuni sau la intrarea în
zona de aşteptare. In cazul unor erori, un proces poate bloca întregul S.O.

Criterii de planificare:
Planificarea proceselor pe procesor va urmări următoarele criterii:

1. Utilizarea procesorului în mod optim


2. Troughtput ( numărul de procese terminate în unitatea de timp)
3. Timpul total de rulare
4. Timpul total de aşteptare ( în coada ready )
5. Timpul de reacţie

Algoritmi de planificare
• Algoritmi de planificare: primul venit, primul servit. Procesele sunt executate în
ordinea sosirii lor în coada rady. Algoritmul este nepreemptiv.
o Avantaje: toate procesele vor ajunge să ruleze odată şi odată;
o Dezavantaje: efectul de convoi.
• Shortest-Job-First: cel mai scutr job mai întâi. Algoritmul măsoară durata rafalei de
instrucţiuni pentru fiecare proces şi încearcă să promoveze pe procesor procesele cu
cea mai scurtă rafală. Poate fi şi preemptiv şi nepreemptiv.
• Algoritm de planificare după priorităţi: fiecărui proces I se asociază un număr numit
prioritate. Algoritmul avansează procesele spre procesor în funcţie de prioritatea
acestora. Este preemptiv sau nepreemptiv. Dezavantaj: blocare indefinită sau
înfometare. O soluţie la problema înfometării ar fi îmbătrânirea= o metodă de a
creşte prioritatea proceselor care asteaptă de mult timp în coadă.
• Roun-Robin este similar cu F.C.F.S. dar este preemptiv; lucrează cu noţiunea de
cuantă de timp; procesele stau în coadă circulară şi se execută în ordine pe durata
cuantei de timp. Dacă rafala de procesor e mai scurtă decât cuanta, procesul cedează
procesorul voluntar; altfel procesul e întrerupt şi trecut în coadă şi pe procesor intră
următorul proces din coada circulară.
• Planificarea cu cozi pe mai multe nivele: procesele se împart pe mai multe categorii
şi fiecare categorie are propriul ei algoritm de planificare şi propria coadă de
procese. Exemplu: procese beckground, procese sistem,procese pe loturi.
• Planificarea cu cozi pe mai multe nivele cu feedback: similar cu V., cu posibilitatea
trecerii unui proces dintr-o coadă în alta.
• In V. şi VI. Cozile au o anumită ordine / prioritate: dacă avem două cozi cu ordin 1 şi
2, întâi se execută procesele din coada 1 şi numai cănd aceasta este goală se execută
şi procese din coada 2.
Managementul memoriei
Cerinţe ale memoriei interne. Există trei cerinţe de bază ale memoriei interne:

• Timpul de acces la memoria internă trebuie să fie cât mai mic posibil; acest lucru se
realizează prin proiectarea adecvată atât a componentei hardware cât şi a celei software
implicate în gestiunea memoriei. Calculatoarele moderne folosesc memoria “cache”, ce
reprezintă un tip de memorie cu acces foarte rapid şi care conţine informaţiile cele mai
recent utilizate de către CPU.
• Dimensiunea memoriei adresabile trebuie să fie cât mai mare posibil, ceea ce se poate
realiza prin conceptual de memorie virtuală.
• Memoria internă trebuie să aibă un cost relativ scăzut.

Funcţiile administratorului memoriei interne sunt:

• Alocarea de spaţiu de memorie internă proceselor.


• Realizarea corespondenţei dintre spaţiul de adrese al procesului şi locaţii de memorie
internă.
• Minimizarea timpului de acces la locaţiile de memorie.

Realizarea acestor funcţii este condiţionată atât de componenta hardware, cât şi de cea software,
conţinută în SO. Odată cu evoluţia componentelor hardware ale SC, s-au schimbat şi strategiile de
administrare a memoriei, pentru a se valorifica aceste îmbunătăţiri. Reciproc, strategiile privind
gestiunea memoriei au evoluat în timp, ceea ce a condus la evoluţia componentelor hardware ale
sistemelor de calcul.

Principalele obiective ale gestiunii memoriei sunt:

• calculul de translatare a adresei(relocare);


• protecţia memoriei;
• organizarea şi alocarea memoriei operative;
• gestiunea memoriei secundare;
• politici de schimb între procese, memoria operativă şi memoria secundară.

Metode clasice de alocare a memoriei


La sistemele monoutilizator este disponibil întreg spaţiul de memorie. Gestiunea acestui spaţiu cade
exclusiv în sarcina utilizatorului. El are la dispoziţie tehnici de suprapunere (overlay) pentru a-şi
putea rula programele mari. Ideea de bază este de a păstra în memoria internă numai acele
instrucţiuni şi date de care este nevoie permanent. Celelalte grupuri de instrucţiuni sunt încărcate în
memoria internă numai atunci când este nevoie de ele, după care sunt evacuate. În figura 3.1 este
ilustrat acest mod de lucru. Porţiunea dintre adresele 0 si a-1 este rezervată nucleului SO, care
rămâne acolo de la încărcare şi până la oprirea sistemului. Între adresele c şi m-1 (dacă memoria are
capacitatea de m locaţii) este spaţiul nefolosit de către programul utilizator activ. Evident, adresa c
variază de la un program utilizator la altul.
Alocarea cu partiţii fixe (MFT-Memory Fix Tasks sau alocare statică). Se presupune că memoria este
împărţită în N zone de lungime fixă numite partiţii. Presupunem că o partiţie i este de lungime Ni şi
este alocată unui proces pe toată durata execuţiei lui, indiferent dacă o ocupă complet sau nu.
Editorul de legături pregăteşte programele pentru a fi rulate într-o zonă de memorie prestabilită.

De obicei, partiţiile au lungimi diferite, astefel încât procesele solicită partiţii în conformitate cu
dimensiunile lor. Dacă un proces are nevoie de nk unităţi de memorie ele poate fi încărcat în oricare
dintre partiţiile i, pentru care N i ≥ nk . În timpul execuţiei procesului, un spaţiu de dimensiune
N i − nk rămâne neutilizat. Acest fenomen se numeşte fragmentare internă. Problema care se pune
este să se aleagă partiţia astfel încât porţiunea de memorie nefolosită să aibă o dimensiune căt mai
mică, adică să se minimizeze diferenţele de forma N i − nk .

Dacă un proces nu încape în nici una dintre partiţiile existente, el nu poate fi executat. Una dintre
problemele cele mai dificile este fixarea acestor dimensiuni. Alegerea unor dimensiuni mai mari
scade probabilitatea ca unele procese să nu poată fi executate, dar scade şi numărul proceselor
active din sistem. În cazul în care există job-uri în sistem care aşteaptă să fie executate, dar toate
partiţiile libere existente la momentul respectiv sunt prea mici, apare fenomenul de fragmentare
externă a memoriei.

Selectarea job-urilor care urmează să fie executate se face de către planificator, în funcţie de
necesarul de memorie necesitat de acestea(pe baza informaţiilor transmise de către utilizator sau
determinate automat de către sistem) şi de partiţiile disponibile existente la momentul respectiv. În
general, există două moduri de legare a proceselor la partiţii:

• Fiecare partiţie are coadă proprie; legarea la o anumită partiţie a proceselor se va face
pe baza necesităţii diferenţei minime între dimensiunea partiţiei şi a procesului (best fit-
cea mai bună potrivire).
• singură coadă pentru toate partiţiile; SO va alege pentru procesul care urmează să intre
în lucru, în ce partiţie se va executa.

Selectarea lucrării se poate face prin:

• strategie de tip FCFS(First Come First Served), care are dezavantajul că o anumită lucrare
trebuie să aştepte în coadă chiar dacă există o partiţie disponibilă în care ar încăpea iar
în faţa lui în coadă se află job-uri care necesită partiţii de dimensiuni mai mari;
• pe baza împărţirii job-urilor în clase de priorităţi, în funcţie de importanţa lor, care
poate avea dezavantajul prezentat mai sus;
• pe baza celei mai bune potrivirii între dimensiunea job-ului cu dimensiunea partiţiei.

Evident că metodele prezentate pot fi combinate. De exemplu, dacă avem mai multe job-uri în
sistem care au aceeaşi prioritate, va fi ales cel care se potriveşte cel mai bine peste partiţia care
devine disponibilă.

Legarea prin cozi proprii partiţiilor este mai simplă din punctul de vedere al SO; în schimb, legarea cu
o singură coadă este mai avantajoasă din punctul de vedere al fragmentării mai reduse a memoriei.
Deoarece în memorie există mai multe job-uri în execuţie, trebuie rezolvate două probleme:
relocarea şi protecţia memoriei. O soluţie a rezolvării ambelor probleme este ca CPU să conţină
două registre speciale, registrul de bază şi registrul limită. Când lucrarea este planificată pentru
execuţie, în registrul de bază este încărcată adresa primei instrucţiuni din fişierul executabil, iar
registrul limită va conţine lungimea partiţiei.

Protecţia memoriei se poate realiza şi prin aşa zisă cheie de protecţie. Fiecare entitate de memorie
alocată (partiţie, pagină etc) conţine o astfel de cheie, iar fiecare entitate de program încarcabilă la
un moment dat(segment, pagină etc) dispune de o cheie de acces. Fiecărei chei de protecţie i se
asociază un şir de biţi prin care se specifică posibilităţile zonei respective. Principalele 3 posibilităţi
sunt R,W,E:

R: din zonă se poate numai citi (read – only).

În astfel de zone se trec de obicei elementele constante ale proceselor.

W: în zonă se poate scrie, eventual zona se poate şterge sau se poate extinde.

E: continutul zonei poate fi executat. În astfel de zone, conţinutul rămâne neschimbat, adică este un
cod reentrant.

Fiecare proces(sau segment de proces) primeşte la încărcare un şir de biţi reprezentând drepturi de
acces. Acestea sunt în corespondenţă cu biţii reprezentând posibilităţile zonei de memorie. În
principiu protecţia memoriei, se asigură executând doi paşi:

La fiecare invocare a unei locaţii de memorie se compară cheia de protecţie cu cheia de acces. În caz
de neconcordanţă, accesul este interzis şi procesul se termină cu un mesaj de eroare.

Dacă cheile coincid, atunci se compară posibilităţile zonei solicitate cu drepturile de acces ale
procesului şi cu acţiunea cerută de proces. Accesul este permis numai în cazul răspunsului afirmativ
la toate aceste comparaţii.

Alocarea cu partiţii fixe a fost folosită la sistemele generaţiei a III-a de calculatoare(IBM 360, Felix
C256/512/1024), dar ea nu este recomandată pentru utilizarea în cadrul sistemelor unde nu se
cunoaşte dinainte de ce spaţiu de memorie are nevoie procesul pentru a fi executat, aspect întâlnit
adesea în cadrul sistemelor de operare moderne.

Interschimbarea job-urilor(job-swapping) apare în cazul sistemelor cu organizarea memoriei în


partiţii fixe, din necesitatea ca la anumite momente unele dintre ele să fie evacuate din memorie iar
altele să fie introduse în memorie. De exemplu, dacă se execută un job şi apare un alt job de
prioritate mai înaltă, jobul de prioritate mai slabă va fi evacuat pe disc.

În mod normal, un job care a fost evacuat va fi readus în aceeaşi partiţie, restricţie impusă atât
strategia de alocare, cât şi de metoda de relocare. Dacă relocarea se face în momentul asamblării
sau în momentul încărcării(relocare statică), job-ul nu poate fi transferat într-o altă partiţie; dacă se
foloseşte relocarea dinamică(cu registru de bază şi registru limită, de exemplu) acest lucru este
posibil.
Interschimbarea joburilor necesită o memorie externă cu acces direct şi rapid, care să poată îngloba
copii ale tuturor imaginilor de memorie utilizator. Toate procesele ale căror imagini de memorie se
află pe disc şi care sunt gata să intre în execuţie se grupează într-o coadă, în timp ce procesele
existente în memorie la momentul respectiv formează altă coadă. Atunci când planificatorul doreşte
să lanseze în execuţie un proces, el apelează dispecerul care verifică dacă procesul se află în
memorie. Dacă nu şi dacă nu există nici o partiţie liberă, dispecerul evacuează din memorie unul
dintre procese, introduce în locul său procesul dorit, reîncarcă registrele şi transferă controlul
procesului selectat. Bineînţeles că o acţiune de acest fel presupune şi cea de salvare a contextului
procesului în execuţie(a conţinuturilor regiştrilor utilizaţi de către acesta), acţiune care este destul de
complexă.

Alocarea cu partiţii variabile (alocare dinamică sau alocare MVT – Memory Variable Task),
reprezintă o extensie a alocării cu partiţii fixe, care permite o exploatare mai eficientă a memoriei
SC.

În cazul multiprogramării cu partiţii fixe, problema cea mai dificilă este optimizarea dimensiunii
partiţiilor, astfel încît să se minimizeze fragmentarea memoriei. De asemenea, se presupune că
joburile au o dimensiune cunoscută, ipoteză care nu este în general adevărată.

Aceste inconveniente pot fi rezolvate dacă se admite modificarea dinamică a dimensiunii partiţiilor,
în funcţie de solicitările adresate sistemului şi de capacitatea de memorie încă disponibilă la un
moment dat. Prin folosirea acestei metode, numărul şi dimensiunea partiţiilor se modifică în timp.

În momentul în care procesul intră în sistem, el este plasat în memorie într-un spaţiu în care încape
cea mai lungă ramură a sa. Spaţiul liber în care a intrat procesul, este acum descompus în două
partiţii: una în care se află procesul, iar cealaltă într-un spaţiu liber care poate fi alocat altui proces.
De asemenea, când un proces îşi termină execuţia spaţiul din memorie ocupat de el este eliberat,
urmând a fi utilizat de către un alt proces. Apare, deci o alternanţă a spaţiilor libere cu cele ocupate.
Pentru a se obţine spaţii libere de dimensiune cât mai mare, SO va declanşa operaţia de alipire a
unor spaţii libere vecine sau de compactare a memoriei (relocare a adreselor), adică de deplasare
a partiţiilor active către partiţia ocupată de către nucleul SO, pentru a se concatena toate
fragmentele de memorie neutilizate. De regulă, operaţia de compactare este complexă,
presupunând efectuarea de operaţii de modificare a adreselor; în practică se aleg soluţii de
compromis, cum ar fi:

• Se lansează periodic compactarea, la un interval de timp fixat, indiferent de starea sistemului.


Procesele care nu au loc în memorie aşteaptă compactarea sau terminarea altui proces.

• Se realizează o compactare parţială pentru a asigura loc numai procesului care asteaptă.

• Se încearcă numai mutarea unuia dintre procese, cu concatenarea spaţiilor rămase libere.

Strategii de administrare a spaţiului din memoria internă. Aşa cu am menţionat anterior, la un


moment dat memoria se prezintă ca o alternanţă a spaţiilor libere cu cele ocupate. Cele libere vor fi
alocate proceselor care cer memorie, iar cele ocupate, când sunt eliberate trebuie, eventual să fie
concatenate cu alte spaţii libere, pentru a obţine zone contigue de dimensiune cât mai mare. Deci,
sunt necesare metode prin care să se ţină evidenţa spaţiilor libere şi a celor ocupate şi să se aloce
spaţiile de memorie solicitate.
Administrarea memoriei folosind liste înlănţuite. Vom presupune că întreaga cantitate de memorie
solicitată la un moment dat este formată dintr-un şir de octeţi consecutivi, care se alocă proceselor
dintr-un rezervor de memorie (numit heap), de unde se ia acestă memorie. De asemenea,
presupunem că există două rutine, una pentru a aloca o zonă de memorie şi de a întoarce adresa ei
de început şi o a doua rutină pentru a elibera spaţiul alocat anterior, în vederea refolosirii lui.

Fiecare zonă liberă începe un cuvânt de control, care conţine un pointer către următoarea porţiune
liberă şi un camp care conţine lungimea zonei respective. La fel se întâmplă în cazul unei zone
ocupate. O zonă ocupată(respectiv liberă) este reperată după cuvântul ei de control. În timp, eate
posibil ca două zone libere să devină adiacente. Sistemul conţine o procedură de comasare a două
zone libere adiacenter.

În momentul în care un proces cere o anumită cantitate de memorie, sistemul caută o zonă liberă de
unde să se ocupe o anumită porţiune. Pentru aceasta se folosesc următoarele strategii:

• Metoda primei potriviri (First-Fit). Esenţa metodei constă în aceea că partiţia solicitată este
alocată în prima zonă liberă în care încape.Principalul avantaj al metodei este simplitatea căutării de
spaţiu liber.

• Metoda celei mai bune potriviri (Best-Fit). Esenţa metodei constă în căutarea acelei zone libere
care lasă după alocare cel mai puţin spaţiu liber. Avantajul metodei constă în economisirea zonelor
de memorie mai mari. Dezavantajul este legat de timpul suplimentar de căutare şi generarea
blocurilor de lungime mică, adică fragmentarea internă excesivă.

Primul neajuns este eliminat parţial dacă lista de spaţii libere se păstrează nu în ordinea crescătoare
a adreselor, ci în ordinea crescătoare a lungimilor spaţiilor libere; în acest caz algoritmul s-ar
complica foarte mult.

• Metoda celei mai rele potriviri (Worst-fit) este duală metodei Best-Fit. Esenţa ei constă în
căutarea acelei zone libere care lasă după alocare cel mai mult spaţiu liber. Deşi numele metodei
sugerează că este vorba despre o metodă mai slabă, în realitate nu este chiar aşa. Faptul că după
alocare rămâne un spaţiu liber mare, este benefic, deoarece în spaţiul rămas poate fi plasată în viitor
o altă partiţie.

Metoda alocării prin camarazi (Buddy-system) se bazează pe reprezentarea binară a adreselor şi


faptul că dimensiunea memoriei interne este un multiplu al unei puteri a lui 2. Presupunem că se
dimensiunea memoriei interne este de forma cx2n, iar unitatea de alocare a memoriei este de forma
2m.

Exemplul 1. Dacă sistemul are o memorie internă de 32 Mo, atunci c=1 şi n=25. Dacă dimensiunea
memoriei interne este de 192 Mo, c=3 şi n=26. De asemenea, se poate considera că unitatea de
alocare este de 256 Ko, adică 28.

Ţinând cont de proprietăţile operaţiilor cu puteri ale lui 2, atât dimensiunile spaţiilor alocate, cât şi
ale celor libere sunt de forma 2k, cu k≤m≤n. În concluzie, sistemul va păstra liste separate ale
adreselor spaţiilor disponibile, în funcţie de dimensiunea lor exprimată ca putere a lui 2. Vom numi
lista de ordin k, lista tuturor adreselor unde încep spaţii libere de dimensiune 2k. Vor exista astfel n-
m+1 liste de spaţii disponibile.
Exemplul 2. Dacă considerăm că dimensiunea memoriei interne este de 192 Mo, vom avea 17 liste:
lista de ordin 8, având dimensiunea unui spaţiu de 256 octeţi; lista de ordin 9, cu spaţii de
dimensiune 512 ş.a.m.d.

Presupunem că, fiecare spaţiu liber(ocupat) de dimensiune 2k, are adresa de început un multiplu de
2k. Două spaţii libere se numesc camarazi de ordinul k, dacă adresele lor A1 şi A2 verifică una dintre
proprietăţile următoare:

A1<A2 , A2=A1+2k şi A1 mod 2k+1=0

A2<A1, A1=A2+2k şi A2 mod 2k*1=0

Această definiţie, exprimă o proprietate fundamentală: Atunci când într-o listă de ordinul k apar doi
camarazi, sistemul îi concatenează într-un spaţiu de dimensiune 2k+1 şi reciproc, un spaţiu de
dimensiune 2k+1 se poate împărţi în două spaţii de dimensiune 2k.

Algoritmul de alocare de memorie.

Pas 1. Fie o numărul de octeţi solicitaţi. Se determină min{p/ m≤p≤n, o≤2p}.

Pas 2. Se determină k=min{i/p≤i≤n şi lista de ordin i este nevidă}.

Pas 3. Dacă k=p, atunci aceasta este alocată şi se şterge din lista de ordinul p altfel se alocă primii 2p
octeţi, se şterge zona din lista de ordinul k şi se creează în schimb alte k-p zone libere, având
dimensiunile 2p, 2p+1,...,2k-1.

Observaţie. Pasul 3 ai algoritmului se bazează pe egalitatea 2k-2p=2p+2p+1+...+2k-1.

Exemplul 3. Se doreşte alocarea a 1000 octeţi, deci p=10. Nu s-au găsit zone libere nici de
dimensiunea 210, nici 211 şi nici 212. Prima zonă liberă de dimensiune 213 are adresa de început 5x213
şi o notăm cu I. Ca rezultat al alocării a fost ocupată zona A de dimensiune 210 şi au fost create încă
trei zone libere: B de dimensiune 210, C de dimensiune 211 şi D de dimensioune 212. Zonele B, C şi D se
trec respectiv în listele de ordine 10, 11 şi 12, iar zona I se şterge din lista de ordin 13.

Algoritmul de eliberare.

Pas 1. Fie 2p dimensiunea zonei eliberate. Se introduce zona respectivă în lista de ordinul p.

Pas 2. k=p

Pas 3. Verifică dacă există camarazi de ordin k:

Dacă da, efectuează comasarea lor; Şterge cei doi camarazi; Introdu noua zonă liberă de dimensiune
2k+1 în lista de ordin k+1.

Pas 4. k=k+1; goto Pas 1.

Exemplul 4. Să presupunem, de exemplu că la un moment dat zonele A, C şi D de dimensiuni 5x213,


respectiv 21x211 şi 11x212 sunt libere, iar zona B de dimensiune 41x211 este ocupată, zonele fiind
adiacente, în ordinea A, B, C, D. În conformitate cu paşii descrişi mai sus, se execută următoarele
acţiuni:
Se trece zona B în lista de ordin 10.

Se observă că zonele A şi B sunt camarazi. Drept urmare, cele două zone sunt comasate şi formează
o nouă zonă X. Zona X se trece în lista de ordin 11, iar zonele A şi B se şterg din lista de ordin 10.

Se observă că zonele X şi C sunt camarazi; ele sunt comasate şi formează o zonă Z care se trece în
lista de ordin 12, înlocuind zonele X şi C din lista de ordin 11.

Se observă că Z şi D sunt camarazi; ele sunt şterse din lista de ordin 12, iar în lista de ordin 13 se
introduce rezultatul comasării lor.
Managementul fişierelor
Este cea mai vizibilă componentă a sistemului, gestionează spaţiul de stocare a datelor pe
memoria extinsă (discuri magnetice, benzi magnetice, discuri optice, stick-uri de memorie).

Fiecare dispozitiv din cele enumerate are propriile caracteristici legate de modul de acces
(secvenţial sau aleator), viteza de acces, rata de transfer a datelor…

Sistemul de operare asigură o vedere uniformă a dispozitivelor de stocare care reprezintă


memoria extinsă a sistemelor de calcul.

Sistemul de operare abstractizează modul de funcţionare a diferitelor dispozitive de stocare


şi defineşte o singură unitate de lucru numită fişier.

Un fişier este o colecţie de informaţii create de utilizator, stocate sub un nume unic.
Sistemul de operare asigură următoarele funcţii în ceea ce priveşte managementul
fişierelor:

• creează şi şterge fişiere;


• creează şi şterge directoare;
• asigură funcţii de manipulare a fişierelor şi directoarelor;
• asigură mecanisme de backup.
Bibliografie

 http://www.freebsd.org

 Silberschatz A., Galvin P.B. and Gagne G. (2005). Operating Systems Concepts, 7th
edn. John Wiley & Sons

 Tanenbaum A.S. (1992). Modern Operating Systems. Englewood Cliffs NJ: Prentice-
Hall.

 An Introduction to Programming with Threads, Andrew D. Birrell