Besturingssystemen: drie eenvoudige stukken. Deel 2: Abstractie: Proces (vertaling)

Inleiding tot besturingssystemen

Hé Habr! Ik zou graag een reeks artikelen onder uw aandacht willen brengen - vertalingen van een interessante literatuur naar mijn mening - OSTEP. Dit materiaal bespreekt vrij diepgaand het werk van Unix-achtige besturingssystemen, namelijk het werken met processen, verschillende planners, geheugen en andere soortgelijke componenten waaruit een modern besturingssysteem bestaat. U kunt het origineel van alle materialen hier bekijken hier. Houd er rekening mee dat de vertaling onprofessioneel (vrij vrij) is gemaakt, maar ik hoop dat ik de algemene betekenis heb behouden.

Labwerk over dit onderwerp is hier te vinden:

Andere delen:

Je kunt ook kijken op mijn kanaal op telegram =)

Laten we eens kijken naar de meest fundamentele abstractie die het besturingssysteem gebruikers biedt: het proces. De definitie van het proces is vrij eenvoudig: dat is het ook lopend programma. Het programma zelf is een levenloos ding dat zich op de schijf bevindt - het is een reeks instructies en mogelijk wat statische gegevens die wachten om gelanceerd te worden. Het is het besturingssysteem dat deze bytes gebruikt en uitvoert, waardoor het programma in iets nuttigs wordt omgezet.
Meestal willen gebruikers meer dan één programma tegelijkertijd uitvoeren. U kunt bijvoorbeeld een browser, game, mediaspeler, teksteditor en dergelijke op uw laptop uitvoeren. In feite kan een typisch systeem tientallen of honderden processen tegelijkertijd uitvoeren. Dit feit maakt het systeem gebruiksvriendelijker, u hoeft zich nooit zorgen te maken of de CPU vrij is, u voert gewoon programma's uit.

Dit roept het probleem op: hoe kunnen we de illusie wekken dat er veel CPU's zijn? Hoe kan het besturingssysteem de illusie wekken van een vrijwel oneindig aantal CPU's, zelfs als je maar één fysieke CPU hebt?

Het besturingssysteem creëert deze illusie door middel van CPU-virtualisatie. Door het ene proces te starten, het vervolgens te stoppen, een ander proces te starten, enzovoort, kan het besturingssysteem de illusie in stand houden dat er veel virtuele CPU's zijn, terwijl er in werkelijkheid een of meer fysieke processors zullen zijn. Deze techniek heet verdeling van CPU-bronnen in de tijd. Met deze techniek kunnen gebruikers zoveel gelijktijdige processen uitvoeren als ze willen. De kosten van deze oplossing zijn de prestaties. Als de CPU door meerdere processen wordt gedeeld, wordt elk proces langzamer verwerkt.
Om CPU-virtualisatie te implementeren, en vooral om het goed te doen, heeft het besturingssysteem zowel ondersteuning op laag als hoog niveau nodig. Er wordt ondersteuning op laag niveau genoemd mechanismen zijn low-level methoden of protocollen die het vereiste deel van de functionaliteit implementeren. Een voorbeeld van een dergelijke functionaliteit is contextwisseling, waardoor het besturingssysteem het ene programma kan stoppen en een ander programma op de processor kan uitvoeren. Deze tijdsindeling is in alle moderne besturingssystemen geïmplementeerd.
Bovenop deze mechanismen is er enige logica ingebouwd in het besturingssysteem, in de vorm van “beleid”. Politiek is een bepaald besluitvormingsalgoritme voor het besturingssysteem. Dergelijk beleid bepaalt bijvoorbeeld welk programma als eerste moet worden gestart (uit een lijst met opdrachten). Dit probleem zal bijvoorbeeld worden opgelost door een beleid genaamd planner (planningsbeleid) en bij het kiezen van een oplossing zal men zich laten leiden door gegevens als: de opstartgeschiedenis (welk programma is de afgelopen minuten het langst gelanceerd), welke belasting dit proces met zich meebrengt (welke soorten programma's zijn gelanceerd), prestatiestatistieken (of het systeem is geoptimaliseerd voor interactieve interactie of voor doorvoer) enzovoort.

Abstractie: proces

De abstractie van een lopend programma dat door het besturingssysteem wordt uitgevoerd, noemen we procede. Zoals eerder vermeld, is een proces eenvoudigweg een programma dat op elk moment wordt uitgevoerd. Een programma waarmee we samenvattende informatie kunnen verkrijgen van verschillende systeembronnen waartoe dit programma toegang heeft of die het beïnvloedt tijdens de uitvoering ervan.
Om de componenten van het proces te begrijpen, moet u de toestanden van het systeem begrijpen: wat het programma kan lezen of veranderen tijdens zijn werking. Op elk moment moet u begrijpen welke elementen van het systeem belangrijk zijn voor de uitvoering van het programma.
Een van de voor de hand liggende elementen van het systeem dat het proces omvat, is geheugen. Instructies bevinden zich in het geheugen. De gegevens die het programma leest of schrijft, bevinden zich ook in het geheugen. Het geheugen dat een proces kan adresseren (de zogenaamde adresruimte) maakt dus deel uit van het proces.
Registers maken ook deel uit van de systeemstatus. Veel instructies zijn gericht op het veranderen van de waarde van registers of het lezen van hun waarde, en dus worden registers ook een belangrijk onderdeel van de werking van het proces.
Opgemerkt moet worden dat de machinestatus ook wordt gevormd uit enkele speciale registers. Bijvoorbeeld, IP - instructieaanwijzer — een verwijzing naar de instructie die het programma momenteel uitvoert. Er is ook stapel aanwijzer en daaraan gerelateerd framewijzer, die worden gebruikt voor het beheer van: functieparameters, lokale variabelen en retouradressen.
Ten slotte hebben programma's vaak toegang tot ROM (alleen-lezen geheugen). Deze “I/O”-informatie (invoer/uitvoer) moet een lijst bevatten met bestanden die momenteel door het proces zijn geopend.

Proces-API

Laten we, om ons begrip van hoe het proces werkt te verbeteren, voorbeelden bestuderen van systeemaanroepen die in elke besturingssysteeminterface zouden moeten worden opgenomen. Deze API's zijn in een of andere vorm beschikbaar op elk besturingssysteem.

creëren (creatie): Het besturingssysteem moet een methode bevatten waarmee u nieuwe processen kunt maken. Wanneer u een opdracht in de terminal invoert of een toepassing start door op een pictogram te dubbelklikken, wordt er een oproep naar het besturingssysteem verzonden om een ​​nieuw proces te maken en vervolgens het opgegeven programma te starten.
verwijdering: Omdat er een interface is voor het maken van een proces, moet het besturingssysteem ook de mogelijkheid bieden om de verwijdering van een proces te forceren. De meeste programma's starten en eindigen uiteraard vanzelf terwijl ze worden uitgevoerd. Anders zou de gebruiker ze graag willen doden en dus zou een interface om het proces te stoppen nuttig zijn.
Wacht (wachten): Soms is het handig om te wachten tot een proces is voltooid, daarom zijn er enkele interfaces beschikbaar die de mogelijkheid bieden om te wachten.
Diverse controle (verschillende controles): Naast het doden en wachten op het proces zijn er ook andere verschillende controlemethoden. De meeste besturingssystemen bieden bijvoorbeeld de mogelijkheid om een ​​proces te bevriezen (de uitvoering ervan voor een bepaalde periode stop te zetten) en het vervolgens te hervatten (de uitvoering voortzetten)
Status (status): Er zijn verschillende interfaces waarmee u informatie kunt verkrijgen over de status van een proces, zoals hoe lang het al actief is of in welke staat het zich momenteel bevindt.

Besturingssystemen: drie eenvoudige stukken. Deel 2: Abstractie: Proces (vertaling)

Procescreatie: details

Een van de interessante dingen is hoe programma's precies in processen worden omgezet. Vooral hoe het besturingssysteem het programma oppakt en uitvoert. Hoe het proces precies tot stand komt.
Allereerst moet het besturingssysteem de programmacode en statische gegevens in het geheugen laden (in de procesadresruimte). Programma's bevinden zich meestal op een schijf of SSD-station in een uitvoerbaar formaat. Het proces van het laden van programma- en statische gegevens in het geheugen vereist dus dat het besturingssysteem die bytes van de schijf kan lezen en ze ergens in het geheugen kan plaatsen.

In vroege besturingssystemen werd het laadproces gretig uitgevoerd, wat betekent dat de volledige code in het geheugen werd geladen voordat het programma werd gestart. Moderne besturingssystemen doen dit lui, dat wil zeggen dat ze alleen stukjes code of gegevens laden als het programma deze nodig heeft tijdens de uitvoering ervan.

Zodra de code en statische gegevens in het besturingssysteemgeheugen zijn geladen, moeten er nog een paar dingen worden gedaan voordat het proces kan worden uitgevoerd. Er moet een bepaalde hoeveelheid geheugen worden toegewezen aan de stapel. Programma's gebruiken de stapel voor lokale variabelen, functieparameters en retouradressen. Het besturingssysteem wijst dit geheugen toe en geeft het aan het proces. De stapel kan ook worden toegewezen met enkele argumenten, met name vult het de parameters van de functie main(), bijvoorbeeld met een array van argc en argv.

Het besturingssysteem kan ook wat geheugen aan de programmaheap toewijzen. De heap wordt door programma's gebruikt om expliciet dynamisch toegewezen gegevens op te vragen. Programma's vragen deze ruimte aan door de functie aan te roepen malloc () en wist het expliciet door de functie aan te roepen vrij(). De heap is nodig voor datastructuren zoals gekoppelde bladen, hashtabellen, bomen en andere. In eerste instantie wordt een kleine hoeveelheid geheugen aan de heap toegewezen, maar na verloop van tijd, terwijl het programma draait, kan de heap meer geheugen aanvragen via de bibliotheek-API-aanroep malloc(). Het besturingssysteem is betrokken bij het toewijzen van meer geheugen om aan deze oproepen te voldoen.

Het besturingssysteem voert ook initialisatietaken uit, vooral taken die verband houden met I/O. Op UNIX-systemen heeft elk proces bijvoorbeeld standaard drie open bestandsdescriptors, voor standaardinvoer, uitvoer en fouten. Met deze handvatten kunnen programma's de invoer van de terminal lezen en informatie op het scherm weergeven.

Door code en statische gegevens in het geheugen te laden, de stapel te maken en te initialiseren en ander werk te doen dat verband houdt met het uitvoeren van I/O-taken, bereidt het besturingssysteem de fase voor die moet worden uitgevoerd. Ten slotte is er nog één laatste taak: het programma door het beginpunt laten lopen, de functie main(). Door de functie main() uit te voeren, draagt ​​het besturingssysteem de CPU-besturing over aan het nieuw gemaakte proces, waardoor het programma wordt uitgevoerd.

Processtatus

Nu we enig begrip hebben van wat een proces is en hoe het wordt gemaakt, gaan we de processtatussen opsommen waarin het zich kan bevinden. In de eenvoudigste vorm kan een proces zich in een van deze toestanden bevinden:
Hardlopen. Wanneer het proces wordt uitgevoerd, draait het op de processor. Dit betekent dat instructies worden uitgevoerd.
Klaar. In de gereedstatus is het proces klaar om te worden uitgevoerd, maar om de een of andere reden voert het besturingssysteem het niet op het opgegeven tijdstip uit.
geblokkeerd. In de geblokkeerde toestand voert een proces een aantal bewerkingen uit die voorkomen dat het gereed is voor uitvoering totdat er een gebeurtenis plaatsvindt. Een veelvoorkomend voorbeeld is dat wanneer een proces een IO-bewerking initieert, dit wordt geblokkeerd zodat een ander proces de processor kan gebruiken.

Besturingssystemen: drie eenvoudige stukken. Deel 2: Abstractie: Proces (vertaling)

Je kunt deze toestanden voorstellen in de vorm van een grafiek. Zoals we op de afbeelding kunnen zien, kan de processtatus naar goeddunken van het besturingssysteem veranderen tussen RUNNING en READY. Wanneer de status van een proces verandert van READY naar RUNNING, betekent dit dat het proces is gepland. In de tegenovergestelde richting - verwijderd uit de lay-out. Op het moment dat een proces GEBLOKKEERD wordt, bijvoorbeeld als ik een IO-bewerking initieer, zal het besturingssysteem het in deze staat houden totdat er een gebeurtenis plaatsvindt, bijvoorbeeld de voltooiing van IO. op dit moment de overgang naar de READY-status en mogelijk onmiddellijk naar de RUNNING-status als het besturingssysteem daartoe besluit.
Laten we eens kijken naar een voorbeeld van hoe twee processen door deze toestanden bewegen. Laten we ons om te beginnen voorstellen dat beide processen actief zijn en dat elk alleen de CPU gebruikt. In dit geval zullen hun staten er als volgt uitzien.

Besturingssystemen: drie eenvoudige stukken. Deel 2: Abstractie: Proces (vertaling)

In het volgende voorbeeld vraagt ​​het eerste proces, na enige tijd te hebben gelopen, om IO en komt in de BLOCKED-status, waardoor een ander proces kan worden uitgevoerd (FIG 1.4). Het besturingssysteem ziet dat proces 0 de CPU niet gebruikt en start proces 1. Terwijl proces 1 actief is, wordt IO voltooid en verandert de status van proces 0 in READY. Ten slotte is proces 1 voltooid en na voltooiing start, voert proces 0 zijn werk uit en voltooit het zijn werk.

Besturingssystemen: drie eenvoudige stukken. Deel 2: Abstractie: Proces (vertaling)

Data structuur

Het besturingssysteem zelf is een programma en net als elk ander programma heeft het een aantal belangrijke datastructuren die verschillende relevante stukjes informatie bijhouden. Om de status van elk proces te volgen, zal het besturingssysteem er enkele ondersteunen proces lijst voor alle processen in de status READY en enige aanvullende informatie om processen bij te houden die momenteel actief zijn. Ook moet het besturingssysteem geblokkeerde processen controleren. Nadat IO is voltooid, moet het besturingssysteem het vereiste proces activeren en gereed maken voor gebruik.

Het besturingssysteem moet bijvoorbeeld de status van de processorregisters behouden. Op het moment dat het proces stopt, wordt de status van de registers opgeslagen in de adresruimte van het proces, en op het moment dat de werking ervan wordt voortgezet, worden de waarden van de registers hersteld en wordt de uitvoering van dit proces dus voortgezet.

Naast de statussen Gereed, Geblokkeerd en Actief zijn er nog enkele andere statussen. Soms kan een proces zich op het moment van creatie in de INIT-status bevinden. Ten slotte kan een proces in de FINAL-status worden geplaatst als het al is voltooid, maar de informatie ervan nog niet is gewist. Op UNIX-systemen wordt deze status aangeroepen zombie-proces. Deze status is handig voor gevallen waarin een ouderproces de retourcode van een kind wil weten. Normaal gesproken betekent 0 een succes en 1 een fout, maar programmeurs kunnen aanvullende uitvoercodes uitgeven om verschillende problemen aan te geven. Wanneer het bovenliggende proces eindigt, voert het een laatste systeemaanroep uit, zoals wait(), om te wachten tot het onderliggende proces is beëindigd en aan het besturingssysteem te signaleren dat het alle gegevens kan wissen die aan het beëindigde proces zijn gekoppeld.

Besturingssystemen: drie eenvoudige stukken. Deel 2: Abstractie: Proces (vertaling)

Kernpunten van de lezing:

Процесс — de belangrijkste abstractie van een actief programma in het besturingssysteem. Op elk gegeven moment kan een proces worden beschreven aan de hand van zijn toestand: de inhoud van het geheugen in zijn adresruimte, de inhoud van processorregisters, inclusief instructiewijzer en stapelwijzer, en IO-informatie, zoals open bestanden die worden gelezen of geschreven.
Proces-API bestaat uit oproepen die programma's naar processen kunnen doen. Meestal zijn dit creatie-, verwijder- of andere oproepen.
● Het proces bevindt zich in een van de vele statussen, waaronder actief, gereed of geblokkeerd. Verschillende gebeurtenissen, zoals planning, uitzonderingen op de planning of wachttijden, kunnen de status van een proces van de ene naar de andere veranderen.
Proceslijst bevat informatie over alle processen in het systeem. Elke vermelding daarin wordt een procescontroleblok genoemd, wat in werkelijkheid een structuur is die alle noodzakelijke informatie over een specifiek proces bevat. 

Bron: www.habr.com

Voeg een reactie