Sisteme de operare: trei piese ușoare. Partea 2: Abstracție: Proces (traducere)

Introducere în sistemele de operare

Bună, Habr! Aș dori să vă prezint atenției o serie de articole-traduceri ale unei literaturi care este interesantă în opinia mea - OSTEP. Acest material examinează destul de profund munca sistemelor de operare asemănătoare Unix, și anume lucrul cu procese, diverse programatoare, memorie și alte componente similare care alcătuiesc un sistem de operare modern. Puteți vedea originalul tuturor materialelor aici aici. Vă rugăm să rețineți că traducerea a fost făcută neprofesionist (destul de liber), dar sper că am păstrat sensul general.

Lucrările de laborator pe acest subiect pot fi găsite aici:

Alte părți:

Puteți verifica și canalul meu la telegramă =)

Să ne uităm la cea mai fundamentală abstractizare pe care sistemul de operare o oferă utilizatorilor: procesul. Definiția procesului este destul de simplă - este programul care rulează. Programul în sine este un lucru lipsit de viață situat pe disc - este un set de instrucțiuni și, eventual, niște date statice care așteaptă să fie lansate. Sistemul de operare este cel care ia acești octeți și îi rulează, transformând programul în ceva util.
Cel mai adesea, utilizatorii doresc să ruleze mai mult de un program în același timp, de exemplu, puteți rula un browser, un joc, un player media, un editor de text și altele asemenea pe laptop. De fapt, un sistem tipic poate rula zeci sau sute de procese simultan. Acest fapt face sistemul mai ușor de utilizat, nu trebuie să vă faceți niciodată griji dacă procesorul este liber, doar rulați programe.

Acest lucru ridică problema: cum să ofere iluzia multor procesoare? Cum poate sistemul de operare să creeze iluzia unui număr aproape infinit de procesoare, chiar dacă aveți doar un procesor fizic?

Sistemul de operare creează această iluzie prin virtualizarea procesorului. Pornind un proces, apoi oprindu-l, pornind un alt proces și așa mai departe, sistemul de operare poate menține iluzia că există multe procesoare virtuale, când de fapt vor exista unul sau mai multe procesoare fizice. Această tehnică se numește împărțirea resurselor CPU în timp. Această tehnică permite utilizatorilor să ruleze câte procese concurente doresc. Costul acestei soluții este performanța - deoarece dacă procesorul este partajat de mai multe procese, fiecare proces va fi procesat mai lent.
Pentru a implementa virtualizarea CPU și mai ales pentru a o face bine, sistemul de operare are nevoie de suport atât la nivel scăzut, cât și la nivel înalt. Se numește suport de nivel scăzut mecanisme sunt metode sau protocoale de nivel scăzut care implementează partea necesară a funcționalității. Un exemplu de astfel de funcționalitate este comutarea de context, care oferă sistemului de operare capacitatea de a opri un program și de a rula un alt program pe procesor. Această diviziune a timpului este implementată în toate sistemele de operare moderne.
Pe deasupra acestor mecanisme este o logică încorporată în sistemul de operare, sub formă de „politici”. Politica este un anumit algoritm decizional pentru sistemul de operare. Astfel de politici, de exemplu, decid ce program trebuie lansat mai întâi (dintr-o listă de comenzi). Deci, de exemplu, această problemă va fi rezolvată printr-o politică numită programator (politica de programare) iar la alegerea unei soluții, aceasta va fi ghidată de date precum: istoricul de pornire (care program a fost lansat cel mai lung în ultimele minute), ce sarcină poartă acest proces (ce tipuri de programe au fost lansate), metrici de performanță (dacă sistemul este optimizat pentru interacțiunea interactivă sau pentru debit) și așa mai departe.

Abstracția: proces

Abstracția unui program care rulează executat de sistemul de operare este ceea ce numim proces. După cum am menționat mai devreme, un proces este pur și simplu un program care rulează, în orice perioadă instantanee de timp. Un program cu ajutorul căruia putem obține informații rezumative din diverse resurse de sistem pe care acest program le accesează sau le afectează în timpul execuției sale.
Pentru a înțelege componentele procesului, trebuie să înțelegeți stările sistemului: ce poate citi sau schimba programul în timpul funcționării sale. În orice moment, trebuie să înțelegeți ce elemente ale sistemului sunt importante pentru execuția programului.
Unul dintre elementele evidente ale sistemului pe care le include procesul este память. Instrucțiunile se află în memorie. Datele pe care le citește sau le scrie programul se află și ele în memorie. Astfel, memoria pe care o poate adresa un proces (numită spațiu de adrese) face parte din proces.
De asemenea, o parte din starea sistemului sunt registrele. Multe instrucțiuni au ca scop modificarea valorii registrelor sau citirea valorii acestora și, astfel, registrele devin, de asemenea, o parte importantă a funcționării procesului.
De remarcat faptul că starea mașinii este formată și din niște registre speciale. De exemplu, IP - indicator de instrucțiuni — un pointer către instrucțiunea pe care programul o execută în prezent. De asemenea este si indicatorul stivei și legat de acesta indicatorul de cadru, care sunt utilizate pentru a gestiona: parametrii funcției, variabilele locale și adresele de retur.
În cele din urmă, programele accesează adesea ROM (memorie doar în citire). Aceste informații „I/O” (intrare/ieșire) ar trebui să includă o listă de fișiere deschise în prezent de proces.

Proces API

Pentru a ne îmbunătăți înțelegerea modului în care funcționează procesul, să studiem exemple de apeluri de sistem care ar trebui incluse în orice interfață de sistem de operare. Aceste API-uri sunt disponibile într-o formă sau alta pe orice sistem de operare.

Crea (creare): sistemul de operare trebuie să includă o metodă care vă permite să creați procese noi. Când introduceți o comandă în terminal sau lansați o aplicație făcând dublu clic pe o pictogramă, este trimis un apel către sistemul de operare pentru a crea un nou proces și apoi lansați programul specificat.
Îndepărtare: Deoarece există o interfață pentru crearea unui proces, sistemul de operare ar trebui să ofere și capacitatea de a forța eliminarea unui proces. Cele mai multe programe se vor porni și se vor termina în mod natural pe măsură ce rulează. În caz contrar, utilizatorul ar dori să-i poată ucide și astfel ar fi utilă o interfață pentru a opri procesul.
Așteaptă (în așteptare): Uneori este util să așteptați ca un proces să se finalizeze, așa că sunt furnizate unele interfețe care oferă posibilitatea de a aștepta.
Control diverse (diverse control): Pe lângă uciderea și așteptarea procesului, există și alte metode diferite de control. De exemplu, majoritatea sistemelor de operare oferă posibilitatea de a îngheța un proces (oprirea execuției acestuia pentru o anumită perioadă) și apoi de a-l relua (continuarea execuției)
Stare (stare): Există diverse interfețe pentru obținerea unor informații despre starea unui proces, cum ar fi cât timp rulează sau în ce stare se află în prezent.

Sisteme de operare: trei piese ușoare. Partea 2: Abstracție: Proces (traducere)

Crearea procesului: Detalii

Unul dintre lucrurile interesante este modul în care programele sunt transformate în procese. Mai ales modul în care sistemul de operare preia și rulează programul. Cum exact este creat procesul.
În primul rând, sistemul de operare trebuie să încarce codul programului și datele statice în memorie (în spațiul de adrese ale procesului). Programele sunt de obicei localizate pe un disc sau o unitate SSD într-un anumit format executabil. Astfel, procesul de încărcare a programului și a datelor statice în memorie necesită ca sistemul de operare să poată citi acești octeți de pe disc și să îi plaseze undeva în memorie.

În sistemele de operare timpurii, procesul de încărcare a fost făcut cu ardoare, ceea ce înseamnă că întregul cod a fost încărcat în memorie înainte de lansarea programului. Sistemele de operare moderne fac acest lucru leneș, adică încarcă bucăți de cod sau date numai atunci când programul le solicită în timpul execuției sale.

Odată ce codul și datele statice sunt încărcate în memoria sistemului de operare, mai sunt câteva lucruri care trebuie făcute înainte ca procesul să poată rula. Trebuie să fie alocată o anumită cantitate de memorie pentru stivă. Programele folosesc stiva pentru variabilele locale, parametrii funcției și adresele returnate. Sistemul de operare alocă această memorie și o dă procesului. Stiva poate fi, de asemenea, alocată cu unele argumente, mai exact umple parametrii funcției main(), de exemplu cu o matrice de argc și argv.

Sistemul de operare poate, de asemenea, să aloce o parte de memorie heap-ului programului. Heap-ul este folosit de programe pentru a solicita în mod explicit date alocate dinamic. Programele solicită acest spațiu apelând funcția malloc () și îl șterge în mod explicit apelând funcția liber(). Heap-ul este necesar pentru structurile de date, cum ar fi foile legate, tabelele hash, copacii și altele. La început, o cantitate mică de memorie este alocată heap-ului, dar în timp, pe măsură ce programul rulează, heap-ul poate solicita mai multă memorie prin apelul API-ului de bibliotecă malloc(). Sistemul de operare este implicat în procesul de alocare a mai multor memorie pentru a ajuta la satisfacerea acestor apeluri.

Sistemul de operare va efectua, de asemenea, sarcini de inițializare, în special cele legate de I/O. De exemplu, pe sistemele UNIX, fiecare proces are în mod implicit 3 descriptori de fișier deschis, pentru intrare, ieșire și eroare standard. Aceste manere permit programelor să citească intrarea de la terminal, precum și să afișeze informații pe ecran.

Astfel, prin încărcarea codului și a datelor statice în memorie, crearea și inițializarea stivei și efectuarea altor lucrări legate de efectuarea sarcinilor I/O, sistemul de operare pregătește etapa pentru executarea procesului. În cele din urmă, mai rămâne o ultimă sarcină: rularea programului prin punctul său de intrare, numită funcție main(). Prin executarea funcției main(), sistemul de operare transferă controlul CPU către procesul nou creat, astfel programul începe să se execute.

Starea procesului

Acum că înțelegem ce este un proces și cum este creat, să enumerăm stările procesului în care se poate afla. În forma sa cea mai simplă, un proces poate fi în una dintre aceste stări:
Alergare. Când rulează, procesul rulează pe procesor. Aceasta înseamnă că instrucțiunile sunt executate.
Gata. În starea gata, procesul este gata de rulare, dar din anumite motive sistemul de operare nu îl execută la momentul specificat.
blocate. În starea blocată, un proces efectuează unele operații care îl împiedică să fie gata de executare până când apare un eveniment. Un exemplu comun este atunci când un proces inițiază o operație IO, acesta devine blocat, astfel încât un alt proces poate folosi procesorul.

Sisteme de operare: trei piese ușoare. Partea 2: Abstracție: Proces (traducere)

Vă puteți imagina aceste stări sub forma unui grafic. După cum putem vedea în imagine, starea procesului se poate schimba între RUNNING și READY, la discreția sistemului de operare. Când starea unui proces se schimbă de la READY la RUNNING, înseamnă că procesul a fost programat. În direcția opusă - eliminat din aspect. În momentul în care un proces devine BLOCAT, de exemplu, inițiez o operație IO, sistemul de operare îl va menține în această stare până când apare un eveniment, de exemplu finalizarea IO. in acest moment trecerea la starea READY si eventual imediat la starea RUNNING daca OS decide acest lucru.
Să ne uităm la un exemplu despre modul în care două procese se deplasează prin aceste stări. Pentru început, să ne imaginăm că ambele procese rulează și fiecare folosește doar CPU. În acest caz, stările lor vor arăta astfel.

Sisteme de operare: trei piese ușoare. Partea 2: Abstracție: Proces (traducere)

În exemplul următor, primul proces, după o perioadă de rulare, solicită IO și intră în starea BLOCKAT, permițând rularea unui alt proces (FIG 1.4). Sistemul de operare vede că procesul 0 nu utilizează CPU și pornește procesul 1. În timp ce procesul 1 rulează, IO este finalizată și starea procesului 0 se schimbă în READY. În cele din urmă, procesul 1 s-a încheiat și, la finalizare, procesul 0 începe, execută și își termină activitatea.

Sisteme de operare: trei piese ușoare. Partea 2: Abstracție: Proces (traducere)

Structură de date

Sistemul de operare în sine este un program și, la fel ca orice alt program, are câteva structuri de date cheie care țin evidența diferitelor informații relevante. Pentru a urmări starea fiecărui proces, sistemul de operare va accepta unele lista de procese pentru toate procesele în starea READY și câteva informații suplimentare pentru a urmări procesele care rulează în prezent. De asemenea, sistemul de operare ar trebui să monitorizeze procesele blocate. După ce IO este finalizată, sistemul de operare trebuie să activeze procesul necesar și să îl pună într-o stare gata de rulare.

De exemplu, sistemul de operare trebuie să păstreze starea registrelor procesorului. În momentul în care procesul se oprește, starea registrelor este stocată în spațiul de adrese al procesului, iar în momentul în care funcționarea acestuia continuă, valorile registrelor sunt restaurate și astfel se continuă execuția acestui proces.

Pe lângă stările gata, blocate, rulante, există și alte stări. Uneori, în momentul creării, un proces poate fi în starea INIT. În cele din urmă, un proces poate fi plasat în starea FINAL atunci când a fost deja finalizat, dar informațiile sale nu au fost încă ștergate. Pe sistemele UNIX, această stare este numită proces zombie. Această stare este utilă pentru cazurile în care un proces părinte dorește să cunoască codul de returnare al unui copil, de exemplu, de obicei 0 semnalează un succes și 1 o eroare, dar programatorii pot emite coduri de ieșire suplimentare pentru a semnala diferite probleme. Când procesul părinte se termină, efectuează un apel final de sistem, cum ar fi wait(), pentru a aștepta ca procesul copil să se termine și să semnaleze sistemului de operare că poate șterge orice date asociate cu procesul încheiat.

Sisteme de operare: trei piese ușoare. Partea 2: Abstracție: Proces (traducere)

Puncte cheie ale prelegerii:

proces — principala abstractizare a unui program care rulează în sistemul de operare. În orice moment, un proces poate fi descris prin starea sa: conținutul memoriei din spațiul său de adrese, conținutul registrelor procesorului, inclusiv pointerul de instrucțiuni și indicatorul de stivă și informațiile IO, cum ar fi fișierele deschise citite sau scrise.
Proces API constă în apeluri pe care programele le pot face către procese. De obicei, acestea sunt crearea, ștergerea sau alte apeluri.
● Procesul se află într-una dintre multele stări, inclusiv rulare, gata, blocat. Diverse evenimente precum programarea, excepțiile de la programare sau așteptările pot schimba starea unui proces de la unul la altul.
Lista proceselor conține informații despre toate procesele din sistem. Fiecare intrare din ea se numește un bloc de control al procesului, care în realitate este o structură care conține toate informațiile necesare despre un anumit proces. 

Sursa: www.habr.com

Adauga un comentariu