Sisteme de operare: Trei piese ușoare. Partea 1: Introducere (traducere)

Introducere în sistemele de operare

Salut, Habr! Vreau să vă prezint o serie de articole-traduceri dintr-o literatură care mi se pare interesantă — OSTEP. Acest material analizează în profunzime funcționarea sistemelor de operare de tip Unix, adică modul în care funcționează procesele, diferitele planificatoare, memoria și alte componente similare, care constituie un sistem de operare modern. Puteți vizualiza originalul tuturor materialelor aici aici. Vă rog să țineți cont că traducerea a fost efectuată neprofesional (destul de liber), dar sper că am păstrat sensul general.

Lucrările de laborator pentru această materie le puteți găsi aici:
— original: pages.cs.wisc.edu/~remzi/OSTEP/Homework/homework.html
— original: github.com/remzi-arpacidusseau/ostep-code
— adaptarea mea personală: github.com/bykvaadm/OS/tree/master/ostep

De asemenea, mă puteți urmări pe canalul meu de telegramă =)

Funcționarea programului

Ce se întâmplă atunci când rulează un program oarecare? Un program lansat execută un lucru simplu — îndeplinește instrucțiuni. Fiecare secundă milioane și chiar miliarde de instrucțiuni sunt extrase de procesor din memoria RAM, acesta le decodează (de exemplu, recunoaște la ce tip aparțin aceste instrucțiuni) și le execută. Acestea pot fi adunarea a două numere, acces la memorie, verificarea unei condiții, transferul la o funcție și așa mai departe. După finalizarea unei instrucțiuni, procesorul trece la executarea alteia. Și așa, instrucțiune după instrucțiune, acestea sunt executate până când programul se încheie.
Acest exemplu, desigur, este prezentat simplificat — în realitate, pentru a accelera funcționarea procesorului, echipamentele moderne permit executarea instrucțiunilor în afara ordinii, calcularea rezultatelor posibile, executarea simultană a instrucțiunilor și astfel de trucuri.

Modelul de calcul von Neumann

Forma simplificată de muncă pe care am descris-o seamănă cu modelul de calcul von Neumann. Von Neumann este unul dintre pionierii sistemelor de computere, de asemenea, este unul dintre autorii teoriei jocurilor. Pe parcursul funcționării programului au loc o mulțime de alte evenimente, funcționează numeroase alte procese și logica externă, ale căror scop principal este simplificarea lansării, funcționării și întreținerii sistemului.
Există un set de software care este responsabil pentru simplificarea lansării programelor (sau chiar permițând lansarea mai multor programe simultan), permițând programelor să partajeze aceeași memorie și să interacționeze cu diverse dispozitive. Acest set de software (program) este, în esență, ceea ce numim sistem de operare, iar sarcinile sale includ monitorizarea funcționării corecte și eficiente a sistemului, precum și asigurarea unei gestionări ușoare a acestuia.

Sistem de operare

Sistemul de operare, pe scurt SO — un complex de programe interconectate, destinat gestionării resurselor computerului și organizării interacțiunii utilizatorului cu computerul..
SO își atinge eficiența în primul rând prin cea mai importantă tehnică — tehnica virtualizării.. SO interacționează cu resursele fizice (procesor, memorie, disc și altele asemenea) și le transformă într-o formă mai generală, cu mai multe capacități și mai ușor de utilizat. Prin urmare, pentru o înțelegere generală, putem compara foarte grosolan sistemul de operare cu o mașină virtuală.
Pentru a permite utilizatorilor să furnizeze comenzi sistemului de operare și astfel să folosească funcționalitățile mașinii virtuale (cum ar fi: lansarea de programe, alocarea de memorie, accesul la fișiere și așa mai departe), sistemul de operare oferă o interfață numită API (interfață de programare a aplicațiilor) și la care se pot face apeluri (call). Un sistem de operare tipic permite efectuarea a sute de apeluri sistemice.
Și, în sfârșit, deoarece virtualizarea permite multor programe să funcționeze (astfel, să partajeze CPU-ul) și să acceseze simultan instrucțiunile și datele lor (astfel partajând memoria), precum și să acceseze discurile (astfel partajând dispozitivele de intrare-ieșire), sistemul de operare este denumit și manager de resurse. Fiecare procesor, disc și memorie sunt resurse ale sistemului și, astfel, una dintre rolurile sistemului de operare devine gestionarea acestor resurse, făcându-le eficient, corect sau, dimpotrivă, în funcție de sarcina pentru care a fost dezvoltat acest sistem de operare.

Virtualizarea CPU

Să analizăm următorul program:
(https://www.youtube.com/watch?v=zDwT5fUcki4&feature=youtu.be)

Sisteme de operare: Trei piese ușoare. Partea 1: Introducere (traducere)

Acesta nu efectuează acțiuni speciale, în esență tot ce face este să apeleze funcția spin(), care are ca sarcină verificarea ciclică a timpului și returnarea după ce a trecut o secundă. Astfel, repetă în mod continuu șirul pe care utilizatorul l-a furnizat ca argument.
Să rulăm acest program și să-i transmitem ca argument caracterul “A”. Rezultatul obținut nu este foarte interesant — sistemul pur și simplu execută programul care afișează periodic caracterul “A”.
Acum să încercăm varianta în care sunt pornite mai multe instanțe ale aceluiași program, dar care afișează litere diferite, pentru a fi mai clar. În acest caz, rezultatul va fi oarecum diferit. Cu toate că avem un singur procesor, programul se execută simultan. Cum este posibil asta? Ei bine, sistemul de operare, cu ajutorul capacităților hardware, creează o iluzie. Iluzia că în sistem există mai mulți procesoare virtuale, transformând un procesor fizic într-un număr teoretic infinit și permițând astfel programelor să pară că se execută simultan. Această iluzie se numește Virtualizarea CPU.
Această situație naște multe întrebări, de exemplu, dacă mai multe programe doresc să se execute simultan, care anume va fi rulată? La această întrebare răspund „politicile” sistemului de operare. Politicile sunt folosite în multe locuri din sistemul de operare și răspund la întrebări de acest fel, fiind de asemenea mecanisme de bază implementate de sistemul de operare. De aici și rolul sistemului de operare ca manager de resurse.

Virtualizarea memoriei

Acum să analizăm memoria. Modelul fizic al memoriei în sistemele moderne este reprezentat ca un array de biți.Pentru a citi din memorie, trebuie să specifici adresa celulei, pentru a obține acces la aceasta. Pentru a scrie sau actualiza date, trebuie de asemenea să specifici datele și adresa celulei în care să fie scrise.
Accesările la memorie au loc constant în timpul execuției programului. Programul stochează în memorie întreaga sa structură de date și se referă la ea, executând diferite instrucțiuni. În același timp, instrucțiunile sunt și ele stocate în memorie, astfel încât accesarea acesteia are loc și la fiecare cerere pentru următoarea instrucțiune.

Apelul malloc()

Să analizăm următoarea programă care alocă o zonă de memorie utilizând un apel malloc() (https://youtu.be/jnlKRnoT1m0):

Sisteme de operare: Trei piese ușoare. Partea 1: Introducere (traducere)

Programul realizează mai multe lucruri. În primul rând, alocă o anumită cantitate de memorie (linia 7), apoi afișează adresa celulei de memorie alocate (linia 9), scrie zero în prima poziție a memoriei alocate. Apoi, programul intră într-un ciclu în care incrementează valoarea scrisă în memorie la adresa stocată în variabila “p”. De asemenea, afișează identificatorul procesului său. Identificatorul procesului este unic pentru fiecare proces lansat. Când lansăm mai multe instanțe, ne întâlnim cu un rezultat interesant: În primul caz, dacă nu facem nimic și pur și simplu lansăm mai multe instanțe, adresele vor fi diferite. Dar acest lucru nu se conformează teoriei noastre! Asta este adevărat, deoarece în distribuțiile moderne, funcția de randomizare a memoriei este activată implicit. Dacă o dezactivăm, vom obține rezultatul așteptat — adresele de memorie ale două programe care rulează simultan vor coincide.

Sisteme de operare: Trei piese ușoare. Partea 1: Introducere (traducere)

Astfel, rezultatul este că două programe independente funcționează cu propriile spații adresabile private, care sunt mapate de sistemul de operare în memoria fizică.Prin urmare, utilizarea adreselor de memorie în cadrul unei singure programe nu va afecta altele, iar fiecărei programe îi pare că are propriul său segment de memorie fizică, complet încredințat ei. Realitatea, însă, este că memoria fizică este un resursă comună, gestionată de sistemul de operare.

Consistență

O altă temă importantă în cadrul sistemelor de operare este consistența. Acest termen este folosit atunci când se discută despre problemele din sistem care pot apărea atunci când se lucrează cu multe lucruri simultan într-o singură programă. Problemele de consistență apar chiar și în sistemul de operare. În exemplele anterioare cu virtualizarea memoriei și procesorului, am înțeles că sistemul de operare gestionează multe lucruri simultan - lansează primul proces, apoi al doilea și așa mai departe. Se pare că un astfel de comportament poate duce la anumite probleme. De exemplu, programele moderne multithreading întâmpină aceste dificultăți.

Să analizăm următorul program:

Sisteme de operare: Trei piese ușoare. Partea 1: Introducere (traducere)

Programul din funcția principală creează două fire, folosind apelul Pthread_create(). În acest exemplu, un fir poate fi gândit ca o funcție care rulează într-un spațiu de memorie alături de alte funcții, iar numărul funcțiilor executate simultan este evident mai mare decât unul. În acest exemplu, fiecare fir pornește și execută funcția worker() care, la rândul ei, pur și simplu incrementează o variabilă.,.

Să rulăm acest program cu argumentul 1000. Așa cum v-ați putut da seama, rezultatul ar trebui să fie 2000, deoarece fiecare fir a incrementat variabila de 1000 de ori. Totuși, nu este atât de simplu. Să încercăm să rulăm programul cu un număr de repetiții cu un ordin mai mare.

Sisteme de operare: Trei piese ușoare. Partea 1: Introducere (traducere)

Furnizând un număr, de exemplu, 100000, ne așteptăm să vedem un rezultat de 200000. Totuși, rulând numărul 100000 de mai multe ori, nu doar că nu vom obține răspunsul corect, dar vom obține și răspunsuri greșite variate. Misterul constă în faptul că pentru a crește numărul sunt necesare trei operații — extragerea numărului din memorie, incrementarea și apoi scrierea din nou a numărului. Deoarece toate aceste instrucțiuni nu sunt efectuate atomic (toate simultan), astfel de lucruri ciudate pot întâmpla. Problema se numește în programare race condition — condiția de cursă. Când forțe necunoscute pot influența în mod necunoscut executarea oricăror operații ale dumneavoastră.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster