Operativsystemer: Tre Enkle Deler. Del 1: Introduktion (oversættelse)

Introduktion til operativsystemer

Hej, Habr! Jeg vil gerne præsentere en serie af oversættelser af en interessant litteratur — OSTEP. I dette materiale beskrives arbejdet med Unix-lignende operativsystemer i dybden, nemlig håndtering af processer, forskellige planlæggere, hukommelse og andre lignende komponenter, der udgør et moderne OS. Du kan se originalen af alt materialet her her. Vær opmærksom på, at oversættelsen er lavet uprofessionelt (temmelig frit), men jeg håber, at jeg har bevaret den overordnede mening.

Laboratoriearbejder om dette emne kan findes her:
— originalen: pages.cs.wisc.edu/~remzi/OSTEP/Homework/homework.html
— originalen: github.com/remzi-arpacidusseau/ostep-code
— min personlige tilpasning: github.com/bykvaadm/OS/tree/master/ostep

Og du kan også tjekke min kanal på telegram =)

Programmets drift

Hvad sker der, når et program kører? Et kørende program udfører én enkel opgave — det udfører instruktioner. Hver sekund trækkes millioner og endda muligvis milliarder af instruktioner ud af RAM'en af processoren, som så dekoder dem (for eksempel genkender hvilken type disse instruktioner tilhører) og udfører dem. Det kan være at lægge to tal sammen, adgang til hukommelse, kontrol af betingelse, spring til en funktion og så videre. Efter afslutningen på én instruktion går processoren videre til at udføre den næste. Og så videre instruktion for instruktion, indtil programmet afsluttes.
Dette eksempel er naturligvis forenklet — faktisk tillader moderne hardware at udføre instruktioner uden for rækkefølge, beregne mulige resultater, udføre instruktioner samtidigt og så videre.

Von Neumann-modellen for beregning

Den forenklede arbejdsform, vi har beskrevet, ligner Von Neumann-modellen for beregning. Von Neumann er en af pionererne inden for computersystemer, og han er også en af forfatterne til spilteori.. Under programudførelsen sker der mange andre begivenheder, mange andre processer og diskré logik arbejder, hvis hovedformål er at forenkle start, drift og vedligeholdelse af systemet.
Der findes en række softwareprogrammer, der er ansvarlige for at gøre det nemt at køre programmer (eller endda tillade kørsel af flere programmer samtidigt). Disse programmer giver mulighed for, at programmer kan dele det samme hukommelse samt interagere med forskellige enheder. Denne softwarepakke kaldes grundlæggende et operativsystem, og dets opgaver inkluderer at overvåge, at systemet fungerer korrekt og effektivt samt at sikre nem styring af systemet.

Operativsystem

Et operativsystem, forkortet OS, er et sæt sammenkoblede programmer, der er designet til at styre computerens ressourcer og organisere brugerens interaktion med computeren..
OS opnår sin effektivitet primært gennem den mest grundlæggende teknik - teknikken virtualisering. OS interagerer med fysiske ressourcer (processor, hukommelse, disk osv.) og transformer dem til en mere generel, mere alsidig og lettere anvendelig form af sig selv. Derfor kan man meget groft sammenligne et operativsystem med en virtuel maskine.
For at muliggøre, at brugerne giver kommandoer til operativsystemet og derved udnytter mulighederne i den virtuelle maskine (såsom: kørsel af programmer, tildeling af hukommelse, adgang til filer osv.), tilbyder operativsystemet et interface kaldet API (application programming interface), som man kan foretage opkald til (call). Et typisk operativsystem giver mulighed for at udføre hundredvis af systemopkald.
Og endelig, da virtualisering muliggør, at mange programmer kan arbejde (dermed dele CPU), og samtidig få adgang til deres instruktioner og data (dermed dele hukommelse), samt få adgang til disks (dermed dele input/output-enheder), kaldes operativsystemet også ressourceforvalter. Hver processor, disk og hukommelse er et systemressource, og derfor bliver en af operativsystemets roller at administrere disse ressourcer effektivt, retfærdigt eller, afhængig af opgaven, som operativsystemet er designet til.

CPU-virtualisering

Lad os se på følgende program:
(https://www.youtube.com/watch?v=zDwT5fUcki4&feature=youtu.be)

Operativsystemer: Tre Enkle Deler. Del 1: Introduktion (oversættelse)

Det udfører ikke nogen særlige handlinger, i bund og grund gør det bare at kalde funktionen spin(), hvis opgave er at cyklistisk tjekke tiden og returnere efter at der er gået et sekund. Således gentager det uendeligt den linje, som brugeren har givet som argument.
Lad os køre dette program og give det argumentet symbolet “A”. Resultatet er ikke særlig interessant — systemet kører simpelthen programmet, som periodisk viser symbolet “A” på skærmen.
Nu prøver vi en variant, hvor mange instanser af det samme program køres, men viser forskellige bogstaver for at gøre det mere forståeligt. I dette tilfælde vil resultatet være en smule anderledes. Selvom vi har én processor, kører programmet samtidig. Hvordan kan det lade sig gøre? Det sker, fordi operativsystemet, med hjælp fra hardware-funktionerne, skaber en illusion. En illusion af, at systemet har flere virtuelle processorer, som omdanner én fysisk processor til teoretisk uendeligt antal og dermed gør det muligt for programmerne at synes at køre samtidig. Denne illusion kaldes CPU-virtualisering.
Et sådant billede rejser mange spørgsmål, for eksempel, hvis flere programmer ønsker at starte samtidig, hvilket program vil så blive startet? Dette spørgsmål besvares af “politikkerne” i OS. Politikker anvendes mange steder i OS og besvarer sådanne spørgsmål, og de er også grundlæggende mekanismer, som OS implementerer. Heraf følger også OS's rolle som ressourcemanager.

Hukommelsesvirtualisering

Lad os nu se på hukommelsen. Den fysiske model af hukommelse i moderne systemer repræsenteres som et array af bytes. For at læse fra hukommelsen skal man angive en celleadresse, for at få adgang til den. For at skrive eller opdatere data skal man også angive dataene og celleadressen, hvor de skal skrives.
Der opstår konstant adgang til hukommelsen under programmets udførelse. Programmet gemmer hele sin datastruktur i hukommelsen og tilgår den, mens det udfører forskellige instruktioner. Instruktionerne opbevares også i hukommelsen, så adgangen til den sker også for hver anmodning om den næste instruktion.

Kald malloc()

Lad os overveje følgende program, der allokerer et område af hukommelsen ved hjælp af kaldet malloc() (https://youtu.be/jnlKRnoT1m0):

Operativsystemer: Tre Enkle Deler. Del 1: Introduktion (oversættelse)

Programmet udfører flere opgaver. For det første allokerer det en vis mængde hukommelse (linje 7), derefter udskriver det adressen på den allokerede celle (linje 9) og skriver nul i den første slot af den allokerede hukommelse. Derefter går programmet ind i en løkke, hvor det inkrementerer værdien, der er gemt i hukommelsen ved adressen i variablen “p”. Det udskriver også proces-id’et for sig selv. Proces-id’et er unikt for hver kørende proces. Hvis vi kører flere kopier, vil vi støde på et interessant resultat: I det første tilfælde, hvis vi ikke gør noget og blot kører flere kopier, så vil adresserne være forskellige. Men det stemmer ikke overens med vores teori! Rigtigt, fordi funktionen til hukommelsesrandomisering som standard er aktiveret i moderne distributioner. Hvis vi slukker den, vil vi få det forventede resultat – adresserne til to samtidige kørende programmer vil være de samme.

Operativsystemer: Tre Enkle Deler. Del 1: Introduktion (oversættelse)

Det viser sig, at to uafhængige programmer arbejder med deres egne private adresseområder, som igen bliver kortlagt af operativsystemet til den fysiske hukommelse. Derfor vil brugen af hukommelsesadresser inden for ét program ikke påvirke andre, og hvert program synes at have sin egen del af den fysiske hukommelse, der er helt til rådighed for dets brug. Virkeligheden er dog, at den fysiske hukommelse er en delt ressource, hvis styring foretages af operativsystemet.

Konsistens

Et andet vigtigt emne inden for operativsystemer er konsistens. Denne term bruges, når der tales om problemer i systemet, der kan opstå, når man arbejder med mange ting samtidigt inden for ét program. Konsistensproblemer opstår endda i selve operativsystemet. I de tidligere eksempler med virtualisering af hukommelse og processor forstod vi, at OS håndterer mange ting på én gang – starter den første proces, derefter den anden og så videre. Det viste sig, at sådan adfærd kan føre til nogle problemer. For eksempel oplever moderne multitrådede programmer sådanne vanskeligheder.

Lad os se på følgende program:

Operativsystemer: Tre Enkle Deler. Del 1: Introduktion (oversættelse)

Programmet i hovedfunktionen opretter to tråde ved hjælp af kaldet Pthread_create(). I dette eksempel kan man tænke på en tråd som en funktion, der kører i et hukommelsesområde sammen med andre funktioner, hvor antallet af kørende funktioner bestemt er mere end én. I dette eksempel starter hver tråd og udfører funktionen worker(), der i sin tur blot inkrementerer en variabel,.

. Vi kører dette program med argumentet 1000. Som du måske allerede har gættet, skal resultatet blive 2000, da hver tråd inkrementerede variablen 1000 gange. Men det er ikke så enkelt. Lad os prøve at køre programmet med et antal gentagelser, der er betydeligt højere.

Operativsystemer: Tre Enkle Deler. Del 1: Introduktion (oversættelse)

Ved at give et tal som 100000, forventer vi at se tallet 200000 som resultat. Men ved at køre tallet 100000 flere gange, vil vi ikke kun opleve, at svaret er forkert, men vi vil også få forskellige forkerte svar. Gåden ligger i, at for at øge tallet kræves der tre operationer - at hente tallet fra hukommelsen, inkrementere det, og derefter skrive tallet tilbage. Da alle disse instruktioner ikke udføres atomarisk (alle på én gang), kan der opstå sådanne mærkelige ting. Dette problem kaldes i programmering race condition — race tilstand. Når usete kræfter på et ukendt tidspunkt kan påvirke udførelsen af dine operationer.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster