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

Introducere în sistemele de operare

Hei 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:
- 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

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

Funcționarea programului

Ce se întâmplă când rulează un program? Un program care rulează face un lucru simplu - execută instrucțiuni. În fiecare secundă, milioane și chiar miliarde de instrucțiuni sunt preluate de procesor din RAM, la rândul său le decodifică (de exemplu, recunoaște ce tip aparțin aceste instrucțiuni) și le execută. Aceasta ar putea fi adăugarea a două numere, accesarea memoriei, verificarea unei stări, trecerea la o funcție și așa mai departe. După executarea unei instrucțiuni, procesorul trece la executarea alteia. Și astfel instrucțiune după instrucțiune, acestea sunt executate până la sfârșitul programului.
Acest exemplu este considerat în mod natural într-o manieră simplificată - de fapt, pentru a accelera procesorul, hardware-ul modern vă permite să executați instrucțiuni în afara secvenței, să calculați rezultate posibile, să executați instrucțiuni simultan și trucuri similare.

Modelul de calcul Von Neumann

Forma simplificată de lucru descrisă de noi este similară cu modelul de calcul Von Neumann. Von Neumann este unul dintre pionierii sistemelor informatice, el este și unul dintre autorii teoriei jocurilor. În timp ce programul rulează, au loc o grămadă de alte evenimente, se rulează multe alte procese și logica terță parte, al căror scop principal este de a simplifica lansarea, operarea și întreținerea sistemului.
Există un set de software care este responsabil pentru ca programele să fie ușor de rulat (sau chiar să permită rularea mai multor programe în același timp), permițând programelor să partajeze aceeași memorie, precum și să comunice cu diferite dispozitive. Un astfel de set de software (software) se numește în esență sistem de operare și sarcinile sale includ monitorizarea faptului că sistemul funcționează corect și eficient, precum și asigurarea ușurinței de gestionare a acestui sistem.

Sistem de operare

Sistemul de operare, abreviat ca OS, este un set de programe interconectate concepute pentru a gestiona resursele computerului și a organiza interacțiunea utilizatorului cu computerul..
Sistemul de operare își atinge eficacitatea în primul rând prin cea mai importantă tehnică - tehnologia virtualizare. Sistemul de operare interacționează cu o resursă fizică (procesor, memorie, disc etc.) și o transformă într-o formă mai generală, mai capabilă și mai ușor de utilizat. Prin urmare, pentru o înțelegere generală, puteți compara foarte aproximativ un sistem de operare cu o mașină virtuală.
Pentru a permite utilizatorilor să dea comenzi sistemului de operare și astfel să utilizeze capacitățile mașinii virtuale (cum ar fi rularea unui program, alocarea memoriei, accesarea unui fișier și așa mai departe), sistemul de operare oferă o interfață numită API (interfață de programare a aplicației) și către care puteți efectua apeluri (apel). Un sistem de operare tipic vă permite să efectuați sute de apeluri de sistem.
În cele din urmă, deoarece virtualizarea permite rularea mai multor programe (prin partajarea procesorului) și accesarea simultană a instrucțiunilor și datelor acestora (deci partajarea memoriei) și accesarea discurilor (astfel partajând dispozitive I/O). ), sistemul de operare este numit și un manager de resurse. Fiecare procesor, disc și memorie este o resursă a sistemului și astfel unul dintre rolurile sistemului de operare devine sarcina de a gestiona aceste resurse, făcând-o eficient, cinstit, sau invers, în funcție de sarcina pentru care acest sistem de operare. este proiectat.

Virtualizarea procesorului

Luați în considerare următorul program:
(https://www.youtube.com/watch?v=zDwT5fUcki4&feature=youtu.be)

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

Nu efectuează nicio acțiune specială, de fapt, nu face decât să apeleze o funcție învârti(), a cărui sarcină este să verifice în mod ciclic timpul și să revină după ce a trecut o secundă. Astfel, repetă la nesfârșit șirul pe care utilizatorul l-a transmis ca argument.
Să rulăm acest program și să-i transmitem caracterul „A” ca argument. Rezultatul nu este deosebit de interesant - sistemul pur și simplu execută un program care afișează periodic simbolul „A” pe ecran.
Acum să încercăm opțiunea când rulează mai multe instanțe ale aceluiași program, dar scoatem litere diferite pentru a fi mai clar. În acest caz, rezultatul va fi ușor diferit. În ciuda faptului că avem un procesor, programul rulează simultan. Cum se întâmplă? Dar se dovedește că sistemul de operare, nu fără ajutorul capabilităților hardware, creează o iluzie. Iluzia că sistemul are mai multe procesoare virtuale, transformând un singur procesor fizic într-un număr teoretic infinit și, astfel, permițând, aparent, programe să ruleze simultan. Aceasta iluzie se numeste Virtualizarea procesorului.
Această imagine ridică multe întrebări, de exemplu, dacă mai multe programe vor să ruleze în același timp, care va fi lansat? „Politicile” OS sunt responsabile pentru această problemă. Politicile sunt folosite în multe locuri în sistemul de operare și răspund la întrebări ca aceasta și sunt mecanismele de bază pe care sistemul de operare le implementează. De aici și rolul sistemului de operare ca manager de resurse.

Virtualizarea memoriei

Acum să ne uităm la memorie. Modelul fizic al memoriei în sistemele moderne este reprezentat ca o matrice de octeți. Pentru a citi din memorie trebuie să specificați adresa celuleipentru a-l accesa. Pentru a scrie sau actualiza datele, trebuie să specificați și datele și adresa celulei în care să le scrieți.
Memoria este accesată constant în timpul execuției programului. Un program stochează întreaga sa structură de date în memorie și o accesează executând diverse instrucțiuni. Instrucțiunile, între timp, sunt și ele stocate în memorie, deci sunt accesate și pentru fiecare solicitare pentru următoarea instrucțiune.

Apelarea lui malloc()

Luați în considerare următorul program, care alocă o zonă de memorie folosind apelul malloc () (https://youtu.be/jnlKRnoT1m0):

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

Programul face mai multe lucruri. Mai întâi, alocă o parte de memorie (linia 7), apoi tipărește adresa celulei alocate (linia 9), scrie zero în primul slot al memoriei alocate. Apoi, programul intră într-o buclă în care incrementează valoarea stocată în memorie la adresa din variabila „p”. De asemenea, tipărește ID-ul procesului. ID-ul procesului este unic pentru fiecare proces care rulează. După ce am lansat mai multe copii, vom da peste un rezultat interesant: în primul caz, dacă nu faceți nimic și rulați doar mai multe copii, atunci adresele vor fi diferite. Dar acest lucru nu se încadrează în teoria noastră! Corect, deoarece distribuțiile moderne au randomizarea memoriei activată în mod implicit. Dacă este dezactivat, obținem rezultatul așteptat - adresele de memorie a două programe care rulează simultan se vor potrivi.

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

Ca rezultat, se dovedește că două programe independente funcționează cu propriile spații de adrese private, care la rândul lor sunt mapate de sistemul de operare în memoria fizică.. Prin urmare, utilizarea adreselor de memorie în cadrul unui program nu îi va afecta în niciun fel pe alții și fiecare program pare să aibă propria sa bucată de memorie fizică, în întregime la dispoziția sa. Realitatea, însă, este că memoria fizică este o resursă partajată care este gestionată de sistemul de operare.

Consecvență

Un alt subiect important din cadrul sistemelor de operare este − consistenta. Acest termen este folosit atunci când se vorbește despre probleme din sistem care pot apărea atunci când se lucrează cu mai multe lucruri în același timp în cadrul aceluiași program. Probleme de consistență apar chiar și în cadrul sistemului de operare însuși. În exemplele anterioare cu virtualizarea memoriei și a procesorului, ne-am dat seama că sistemul de operare gestionează multe lucruri în același timp - începe primul proces, apoi al doilea și așa mai departe. După cum se dovedește, acest comportament poate duce la unele probleme. Deci, de exemplu, programele moderne multi-threaded se confruntă cu astfel de dificultăți.

Luați în considerare 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ă în același spațiu de memorie alături de alte funcții, cu mai multe funcții rulând în același timp. În acest exemplu, fiecare fir începe și execută o funcție worker() care, la rândul său, pur și simplu incrementează variabila,.

Să rulăm acest program cu un argument de 1000. După cum probabil ați ghicit, rezultatul ar trebui să fie 2000 deoarece fiecare fir a incrementat variabila de 1000 de ori. Totuși, totul nu este atât de simplu. Să încercăm să rulăm programul cu un ordin de mărime mai multe repetări.

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

Introducând un număr, de exemplu, 100000, ne așteptăm să vedem rezultatul ca fiind numărul 200000. Cu toate acestea, dacă rulăm numărul 100000 de mai multe ori, nu numai că nu vom vedea răspunsul corect, dar vom primi și diferite răspunsuri incorecte. Răspunsul constă în faptul că pentru a crește numărul, sunt necesare trei operații - extragerea numărului din memorie, creșterea și apoi scrierea înapoi a numărului. Deoarece toate aceste instrucțiuni nu sunt executate atomic (toate în același timp), se pot întâmpla lucruri ciudate ca acesta. Această problemă se numește în programare race condition - condiție de cursă. Când forțe necunoscute într-un moment necunoscut pot afecta executarea oricăreia dintre operațiunile tale.

Sursa: www.habr.com

Adauga un comentariu