Introduktion till operativsystem
Hej, Habr! Jag vill presentera för er en serie översĂ€ttningsartiklar av en intressant litteratur â OSTEP. I detta material behandlas djupgĂ„ende hur unix-liknande operativsystem fungerar, nĂ€mligen arbetet med processer, olika schemalĂ€ggare, minne och andra liknande komponenter som utgör ett modernt OS. Originalet av allt material kan du se hĂ€r . Observera att översĂ€ttningen Ă€r utförd oprofessionellt (relativt fritt), men jag hoppas att jag har bevarat den övergripande meningen.
Laborationsarbeten för detta Àmne kan hittas hÀr:
- original:
- original:
- min personliga anpassning:
Andra delar:
Och du kan ocksÄ kolla in min kanal pÄ =)
LĂ„t oss titta pĂ„ den mest grundlĂ€ggande abstraktionen som OS erbjuder anvĂ€ndare: processen. Definitionen av en process Ă€r ganska enkel â det Ă€r ett körande program. Ett program i sig Ă€r en livlös sak, belĂ€gen pĂ„ disken â det Ă€r en uppsĂ€ttning instruktioner och möjligen nĂ„gra statiska data, som vĂ€ntar pĂ„ att bli startade. Det Ă€r operativsystemet som tar dessa byte och kör dem, vilket förvandlar programmet till nĂ„got nyttigt.
Oftast vill anvÀndare köra mer Àn ett program samtidigt, till exempel kan du köra en webblÀsare, ett spel, en mediaplayer, en textredigerare och sÄ vidare pÄ din laptop. Faktiskt kan ett typiskt system köra tiotals och hundratals processer samtidigt. Denna fakta gör systemet enklare att anvÀnda, du behöver aldrig oroas för om CPU:n Àr ledig, du startar bara programmen.
HÀrav uppstÄr problemet: hur ska man skapa illusionen av flera CPU:er? Hur kan operativsystemet skapa illusionen av praktiskt taget ett oÀndligt antal CPU:er, Àven om du bara har en fysisk CPU?
Operativsystemet skapar denna illusion genom CPU-virtualisering. Genom att köra en process, sedan stanna den, köra en annan process och sĂ„ vidare, kan OS upprĂ€tthĂ„lla illusionen av att det finns mĂ„nga virtuella CPU:er, Ă€ven om det i sjĂ€lva verket bara handlar om en eller flera fysiska processorer. Denna teknik kallas CPU-resurser tidsdelning. Denna teknik gör det möjligt för anvĂ€ndare att köra sĂ„ mĂ„nga samtidiga processer som de önskar. Priset för denna lösning Ă€r prestanda â eftersom om CPU:n delas av flera processer kommer varje process att bearbetas lĂ„ngsammare.
För att möjliggöra CPU-virtualisering, och sĂ€rskilt för att göra det bra, krĂ€ver operativsystemet bĂ„de lĂ„g- och hög-nivĂ„ stöd. LĂ„g-nivĂ„ stöd kallas mekanismer â det Ă€r lĂ„g-nivĂ„ metoder eller protokoll som implementerar den nödvĂ€ndiga funktionaliteten. Ett exempel pĂ„ sĂ„dan funktionalitet Ă€r kontextvĂ€xling, som ger operativsystemet möjlighet att stoppa ett program och starta ett annat program pĂ„ processorn. Denna tidsdelning Ă€r implementerad i alla moderna operativsystem.
Ovanför dessa mekanismer finns viss logik inbyggd i operativsystemet, i form av "policys". Policy â Ă€r en specifik algoritm för beslutsfattande i operativsystemet. SĂ„dana policies avgör till exempel vilket program som ska köras (frĂ„n kommandolistan) först. SĂ„ledes kommer en policy, som kallas schemalĂ€ggare (scheduling policy) att vĂ€gledas av information som: starthistorik (vilket program har kört lĂ€ngst under den senaste minuten), vilken belastning varje process har (vilka typer av program som har körts), prestandametrik (Ă€r systemet optimerat för interaktivt samspel eller för genomströmning) och sĂ„ vidare.
Abstraktion: process
Abstraktionen av ett körande program, utfört av operativsystemet, Àr vad vi kallar process. Som redan nÀmnts Àr en process helt enkelt ett körande program vid en viss tidpunkt. Programmet med vilket vi kan fÄ sammanfattande information frÄn olika systemresurser, och som programmet fÄr tillgÄng till eller pÄverkar under sin körning.
För att förstÄ komponenterna i en process mÄste vi förstÄ systemtillstÄnd: vad programmet kan lÀsa eller Àndra under sin körning. Vid varje given tidpunkt mÄste vi förstÄ vilka systemelement som Àr viktiga för programmets genomförande.
Ett av de uppenbara elementen i systemets tillstÄnd som processen inkluderar Àr minnet. Instruktionerna lagras i minnet. Data som programmet lÀser eller skriver lagras ocksÄ i minnet. DÀrför Àr det minne som processen kan adressera (det sÄ kallade adressutrymmet) en del av processen.
En annan del av systemets tillstÄnd Àr registren. MÄnga instruktioner syftar till att Àndra vÀrdet av registren eller lÀsa deras vÀrde, vilket gör att registren ocksÄ blir en viktig del av processens funktion.
Det bör noteras att maskinens tillstĂ„nd ocksĂ„ bestĂ„r av vissa specialregister. Till exempel, IP â instruction pointer â pekaren till den instruktion som programmet för nĂ€rvarande exekverar. Det finns ocksĂ„ stack pointer och den relaterade frame pointer, som anvĂ€nds för att hantera: funktionsparametrar, lokala variabler och Ă„tervĂ€ndsadresser.
Slutligen hÀnvisar program ofta till ROM (lÀsminne). Den information om 'I/O' (ingÄng/utgÄng) bör innehÄlla en lista över filer som processen har öppnat för tillfÀllet.
Process API
För att förbÀttra förstÄelsen av processens funktion ska vi studera exempel pÄ systemanrop som mÄste ingÄ i varje operativsystems grÀnssnitt. Dessa API Àr pÄ ett eller annat sÀtt tillgÀngliga pÄ varje operativsystem.
â Skapa (skapande): Operativsystemet mĂ„ste ha nĂ„gon metod som gör det möjligt att skapa nya processer. NĂ€r du skriver ett kommando i terminalen eller startar en applikation genom att dubbelklicka pĂ„ ikonen, skickas en begĂ€ran till operativsystemet för att skapa en ny process och sedan starta det angivna programmet.
â Ta bort: Eftersom det finns ett grĂ€nssnitt för att skapa en process, mĂ„ste operativsystemet ocksĂ„ erbjuda möjlighet till tvingad borttagning av processen. De flesta program kommer naturligtvis att startas och avslutas av sig sjĂ€lva i takt med att de körs. I annat fall skulle anvĂ€ndaren vilja kunna avsluta dem, och ett grĂ€nssnitt för att stoppa processen skulle dĂ€rför vara anvĂ€ndbart.
â VĂ€nta (vĂ€ntande): Ibland Ă€r det anvĂ€ndbart att vĂ€nta pĂ„ att processen ska slutföras, sĂ„ vissa grĂ€nssnitt tillhandahĂ„lls för att möjliggöra detta.
â Ăvrig kontroll (olika styrningar): Förutom att döda och vĂ€nta pĂ„ processer finns det ocksĂ„ olika kontrollmetoder. Till exempel ger de flesta operativsystem möjligheten att frysa en process (stoppa dess körning under en viss tid) och att sedan Ă„teruppta den (fortsĂ€tta exekveringen).
â Status (status): Det finns olika grĂ€nssnitt för att fĂ„ information om en process, sĂ„som hur lĂ€nge den har körts eller vilket tillstĂ„nd den befinner sig i.

Skapande av process: detaljer
En intressant aspekt Àr hur program faktiskt omvandlas till processer. SÀrskilt hur operativsystemet laddar och startar ett program. Hur en process skapas konkret.
Först mÄste operativsystemet ladda programmets kod och statiska data till minnet (i processens adressutrymme). Program ligger vanligtvis pÄ disken eller en solid-state-enhet i nÄgot körbart format. DÀrför krÀver processen att ladda program och statiska data till minnet att operativsystemet kan lÀsa dessa byte frÄn disken och placera dem nÄgonstans i minnet.
I tidiga operativsystem utfördes laddningsprocessen ivrigt (eagerly), vilket betyder att koden laddades helt till minnet innan programmet startades. Moderna operativsystem gör detta lat (lazily), genom att ladda bitar av kod eller data bara nÀr de behövs av programmet under dess körning.
Efter att koden och de statiska data har laddats in i minnet mÄste operativsystemet utföra ytterligare nÄgra steg innan processen kan startas. Ett visst minnesutrymme mÄste avsÀttas för stacken. Program anvÀnder stacken för lokala variabler, funktionsparametrar och returadresser.. Operativsystemet avsÀtter detta minne och ger det till processen. Stacken kan ocksÄ avsÀttas med vissa argument, specifikt fyller den funktionsparametrarna för main(), som till exempel en array av argc och argv.
Operativsystemet kan ocksÄ avsÀtta ett visst minnesutrymme för programmets heap. Heapen anvÀnds av program för explicit begÀrd dynamiskt allokerad data.. Program begÀr detta utrymme genom att anropa funktionen malloc() och frigör det explicit genom att anropa funktionen free()Högen behövs för datatyper som: lÀnkade listor, hash-tabeller, trÀd och andra. I början reserveras en liten mÀngd minne för högen, men med tiden kan högens minnesbegÀrningar öka genom biblioteks-API-anropet malloc(). Operativsystemet Àr involverat i att tilldela mer minne för att hjÀlpa till att uppfylla dessa begÀrningar.
Operativsystemet kommer ocksÄ att utföra initialiseringsuppgifter, sÀrskilt de som rör in- och utmatning. Till exempel har varje process i UNIX-system som standard 3 öppna filbeskrivare för standard inmatnings-, utmatnings- och felström. Dessa beskrivare gör det möjligt för program att lÀsa in data frÄn terminalen samt att skriva ut information pÄ skÀrmen.
Genom att ladda kod och statiska data i minnet, skapa och initiera stacken och Àven utföra annat relaterat till in- och utmatningsuppgifter förbereder operativsystemet plattformen för processens utförande. Till slut finns det en sista uppgift: att köra programmet via dess ingÄngspunkt, kallad funktionen main(). NÀr kontrollen övergÄr till funktionen main() överlÀmnar operativsystemet kontrollen till den nyligen skapade processen, vilket gör att programmet börjar köras.
Processens tillstÄnd
Nu nÀr vi har en viss förstÄelse av vad en process Àr och hur den skapas, lÄt oss lista de tillstÄnd som en process kan befinna sig i. I sin enklaste form kan processen befinna sig i ett av dessa tillstÄnd:
â Running. I körande tillstĂ„nd körs processen pĂ„ processorn. Det innebĂ€r att instruktionerna utförs.
â Redo. I klart tillstĂ„nd Ă€r processen redo att starta, men av nĂ„gon anledning utför operativsystemet den inte vid den aktuella tidpunkten.
â Blockerad. I blockerat tillstĂ„nd utför processen operationer som gör att den inte Ă€r redo att köras förrĂ€n en viss hĂ€ndelse intrĂ€ffar. Ett vanligt exempel Ă€r nĂ€r processen initierar en IO-operation, blir den blockerad och pĂ„ sĂ„ sĂ€tt kan en annan process anvĂ€nda processorn.

TĂ€nk dig dessa tillstĂ„nd som ett graf. Som vi kan se pĂ„ bilden kan processens tillstĂ„nd vĂ€xla mellan RUNNING och READY efter operativsystemets (OS) beslut. NĂ€r processens tillstĂ„nd förĂ€ndras frĂ„n READY till RUNNING betyder det att processen har schemalagts. I motsatt riktning â avbruten frĂ„n schemalĂ€ggning. I det ögonblick processen blir BLOCKED, till exempel under en IO-operation, kommer OS att hĂ„lla den i detta tillstĂ„nd tills en viss hĂ€ndelse intrĂ€ffar, som exempelvis avslutandet av IO. I det ögonblicket övergĂ„r den till tillstĂ„ndet READY och kan omedelbart gĂ„ till tillstĂ„ndet RUNNING, om OS sĂ„ beslutar.
LÄt oss titta pÄ ett exempel pÄ hur tvÄ processer gÄr igenom dessa tillstÄnd. Först förestÀller vi oss att bÄda processerna Àr aktiva och vardera anvÀnder endast CPU. I sÄdana fall kommer deras tillstÄnd att se ut pÄ följande sÀtt.

I nÀsta exempel begÀr den första processen IO efter en tid av arbete och övergÄr till tillstÄndet BLOCKED, vilket ger den andra processen möjlighet att starta (FIG 1.4). OS ser att process 0 inte anvÀnder CPU och startar process 1. Under tiden som process 1 körs avslutas IO och status för process 0 Àndras till READY. Slutligen avslutas process 1, och nÀr den Àr klar startas process 0, körs och avslutar sin uppgift.

Databasstruktur
Operativsystemet sjÀlv Àr ett program och precis som alla andra program har den vissa nyckeldata strukturer som spÄrar olika relevanta informationsbitar. För att spÄra tillstÄndet för varje process kommer OS att underhÄlla en viss processlista för alla processer i tillstÄndet READY och viss ytterligare information för att spÄra de processer som för nÀrvarande körs. Dessutom mÄste OS spÄra och blockera processer. Efter att IO avslutats Àr OS skyldig att vÀcka den nödvÀndiga processen och Äterföra den till ett tillstÄnd av beredskap för start.
SÄ, till exempel, mÄste OS spara tillstÄndet för processorns register. Vid stopp av processen sparas registertillstÄndet i processens adressutrymme, och vid fortsÀttning av dess arbete ÄterstÀlls registervÀrdena och processen fortsÀtter dÀrmed sin utförande.
Förutom tillstÄnden ready, blocked, running finns det Àven vissa andra tillstÄnd. Ibland kan en process vid skapandet ha tillstÄndet INIT. Slutligen kan processen sÀttas i tillstÄndet FINAL nÀr den redan har avslutats, men informationen om den har Ànnu inte rensats. I UNIX-system kallas detta tillstÄnd zombiprocess. Detta tillstÄnd Àr anvÀndbart nÀr förÀldraprocessen vill veta ÄtervÀndande kod frÄn barnprocessen, till exempel signalerar vanligtvis 0 en framgÄngsrik avslutning, medan 1 indikerar ett fel, men programmerare kan skapa ytterligare utgÄngskoder som signalerar olika problem. Vid avslutning gör förÀldraprocessen det sista systemanropet, till exempel wait(), för att vÀnta pÄ att barnprocessen ska avslutas och signalera OS att det Àr okej att rensa bort data relaterade till den avslutade processen.

Centrykt punkter i förelÀsningen:
â Process Ă€r den huvudsakliga abstraktionen av ett körande program i OS. Vid varje given tidpunkt kan en process beskrivas utifrĂ„n dess tillstĂ„nd: minnesinnehĂ„llet i dess adressutrymme, innehĂ„llet i processorns register, inklusive instruction pointer och stack pointer samt information om IO, sĂ„som öppna filer som lĂ€ses eller skrivs.
â Process API bestĂ„r av anrop som program kan göra angĂ„ende processer. Vanligtvis handlar det om anrop för skapande, borttagning eller andra.
â Processen befinner sig i ett av mĂ„nga tillstĂ„nd, inklusive running, ready, blocked. Olika hĂ€ndelser, sĂ„som schemalĂ€ggning, uteslutning frĂ„n schemalĂ€ggning eller vĂ€ntan kan omvandla en process frĂ„n ett tillstĂ„nd till ett annat.
â Processlistan innehĂ„ller information om alla processer i systemet. Varje post i den kallas process control block, vilket faktiskt Ă€r en struktur som innehĂ„ller all nödvĂ€ndig information om en specifik process.â
KĂ€lla: habr.com
