Operativsystemer: Tre enkle stykker. Del 1: Intro (oversettelse)

Introduksjon til operativsystemer

Hei Habr! Jeg vil gjerne gjøre deg oppmerksom på en serie artikler-oversettelser av en interessant litteratur etter min mening - OSTEP. Dette materialet diskuterer ganske dypt arbeidet til unix-lignende operativsystemer, nemlig arbeid med prosesser, ulike planleggere, minne og andre lignende komponenter som utgjør et moderne OS. Du kan se originalen av alt materiale her her. Vær oppmerksom på at oversettelsen ble gjort uprofesjonelt (ganske fritt), men jeg håper jeg beholdt den generelle betydningen.

Laboratoriearbeid om dette emnet finner du her:
- original: pages.cs.wisc.edu/~remzi/OSTEP/Homework/homework.html
- original: github.com/remzi-arpacidusseau/ostep-code
- min personlige tilpasning: github.com/bykvaadm/OS/tree/master/ostep

Du kan også sjekke kanalen min på telegram =)

Programdrift

Hva skjer når et program kjører? Et kjørende program gjør en enkel ting - det utfører instruksjoner. Hvert sekund hentes millioner og muligens milliarder av instruksjoner av prosessoren fra RAM, i sin tur dekoder den dem (for eksempel gjenkjenner den hvilken type disse instruksjonene tilhører) og utfører dem. Dette kan være å legge til to tall, få tilgang til minnet, sjekke en tilstand, hoppe til en funksjon og så videre. Etter utførelse av en instruksjon, fortsetter prosessoren til utførelse av en annen. Og så instruksjon etter instruksjon, blir de utført til programmet avsluttes.
Dette eksemplet anses naturlig å være forenklet - faktisk, for å øke hastigheten på prosessoren, lar moderne maskinvare deg utføre instruksjoner utenfor tur, beregne mulige resultater, utføre instruksjoner samtidig og lignende triks.

Von Neumann beregningsmodell

Den forenklede arbeidsformen beskrevet av oss ligner på Von Neumann-modellen for beregning. Von Neumann er en av pionerene innen datasystemer, han er også en av forfatterne av spillteori. Mens programmet kjører, finner en haug med andre hendelser sted, mange andre prosesser og tredjeparts logikkarbeid, hvis hovedformål er å forenkle lansering, drift og vedlikehold av systemet.
Det er et sett med programvare som er ansvarlig for å gjøre programmer enkle å kjøre (eller til og med tillate flere programmer å kjøre samtidig), som lar programmer dele det samme minnet og kommunisere med forskjellige enheter. Et slikt sett med programvare (programvare) kalles i hovedsak operativsystemet og dets oppgaver inkluderer å overvåke at systemet fungerer riktig og effektivt, samt å sikre enkel administrasjon av dette systemet.

Operativsystem

Et operativsystem, forkortet som et OS, er et sett med sammenhengende programmer designet for å administrere datamaskinressurser og organisere brukerinteraksjon med en datamaskin..
OS oppnår sin effektivitet i første omgang, gjennom den viktigste teknikken - teknikken virtualisering. OS samhandler med en fysisk ressurs (prosessor, minne, disk, etc.) og transformerer den til en mer generell, kraftigere og lettere å bruke form av seg selv. Derfor, for en generell forståelse, kan du veldig grovt sammenligne operativsystemet med en virtuell maskin.
For å tillate brukere å gi kommandoer til operativsystemet og dermed bruke egenskapene til den virtuelle maskinen (som å kjøre et program, tildele minne, få tilgang til en fil og så videre), gir operativsystemet et grensesnitt kalt API (applikasjonsprogrammeringsgrensesnitt) og som du kan ringe til (ringe). Et typisk operativsystem lar hundrevis av systemanrop foretas.
Til slutt, siden virtualisering tillater flere programmer å kjøre (og dermed dele CPU), og samtidig få tilgang til instruksjonene og dataene deres (og dermed dele minne), og få tilgang til disker (og dermed dele I/O-enheter). ), kalles operativsystemet også en ressurssjef. Hver prosessor, disk og minne er en ressurs i systemet, og dermed blir en av rollene til operativsystemet oppgaven med å administrere disse ressursene, gjøre det effektivt, ærlig eller omvendt, avhengig av oppgaven som dette operativsystemet for. er designet.

CPU-virtualisering

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

Operativsystemer: Tre enkle stykker. Del 1: Intro (oversettelse)

Den utfører ingen spesielle handlinger, faktisk, alt den gjør er å kalle en funksjon spinne(), hvis oppgave er å gå gjennom tidskontrollen og returnere etter ett sekund. Dermed gjentar den strengen som brukeren sendte som et argument på ubestemt tid.
La oss kjøre dette programmet og gi det tegnet "A" som et argument. Resultatet er ikke spesielt interessant - systemet kjører ganske enkelt et program som med jevne mellomrom viser tegnet "A".
La oss nå prøve alternativet når mange forekomster av det samme programmet kjører, men sender ut forskjellige bokstaver for å gjøre det klarere. I dette tilfellet vil resultatet bli noe annerledes. Til tross for at vi har én prosessor, kjøres programmet samtidig. Hvordan skjer det? Men det viser seg at operativsystemet, ikke uten hjelp av maskinvarefunksjoner, skaper en illusjon. Illusjonen om at systemet har flere virtuelle prosessorer, gjør en enkelt fysisk prosessor til et teoretisk uendelig antall og dermed lar tilsynelatende programmer kjøre samtidig. Denne illusjonen kalles CPU-virtualisering.
Dette bildet reiser mange spørsmål, for eksempel hvis flere programmer ønsker å kjøre samtidig, hvilket vil bli lansert? "Retningslinjene" til OS er ansvarlige for dette spørsmålet. Politikker brukes mange steder i OS og svarer på spørsmål som dette, og er de grunnleggende mekanismene som OS implementerer. Derfor rollen til OS som en ressursforvalter.

Minnevirtualisering

La oss nå se på minnet. Den fysiske modellen av minne i moderne systemer er representert som en rekke byte.. For å lese fra minnet må du spesifisere mobiladressefor å få tilgang til den. For å skrive eller oppdatere data må du også spesifisere dataene og adressen til cellen hvor de skal skrives.
Minnet får kontinuerlig tilgang under programkjøring. Et program lagrer hele datastrukturen i minnet og får tilgang til den ved å utføre ulike instruksjoner. Instruksjonene er i mellomtiden også lagret i minnet, så det er også tilgjengelig for hver forespørsel om neste instruksjon.

malloc() kall

Tenk på følgende program, som tildeler et minneområde ved å bruke anropet malloc () (https://youtu.be/jnlKRnoT1m0):

Operativsystemer: Tre enkle stykker. Del 1: Intro (oversettelse)

Programmet gjør flere ting. Først allokerer den noe minne (linje 7), skriver deretter ut adressen til den tildelte cellen (linje 9), skriver null til det første sporet i det tildelte minnet. Deretter går programmet inn i en sløyfe der det øker verdien som er lagret i minnet på adressen i "p"-variabelen. Den skriver også ut prosess-IDen til seg selv. Prosess-IDen er unik for hver pågående prosess. Etter å ha lansert flere kopier, vil vi snuble over et interessant resultat: I det første tilfellet, hvis du ikke gjør noe og bare kjører flere kopier, vil adressene være forskjellige. Men dette faller ikke inn under vår teori! Riktig, siden moderne distribusjoner har minnerandomisering aktivert som standard. Hvis den er deaktivert, får vi det forventede resultatet - minneadressene til to programmer som kjører samtidig vil samsvare.

Operativsystemer: Tre enkle stykker. Del 1: Intro (oversettelse)

Som et resultat viser det seg at to uavhengige programmer fungerer med sine egne private adresserom, som igjen er kartlagt av operativsystemet i fysisk minne. Derfor vil bruken av minneadresser i ett program ikke påvirke andre på noen måte, og det ser ut til at hvert program har sitt eget fysiske minne, helt gitt til det. Realiteten er imidlertid at fysisk minne er en delt ressurs som administreres av operativsystemet.

Konsistens

Et annet av de viktige temaene innen operativsystemer er − konsistens. Dette begrepet brukes når man snakker om problemer i systemet som kan oppstå når man jobber med mange ting samtidig innenfor samme program. Konsistensproblemer oppstår selv innenfor selve operativsystemet. I de forrige eksemplene på minne- og prosessorvirtualisering innså vi at operativsystemet styrer mange ting samtidig - det starter den første prosessen, deretter den andre, og så videre. Som det viste seg, kan denne oppførselen føre til noen problemer. Så for eksempel opplever moderne flertrådsprogrammer slike vanskeligheter.

Tenk på følgende program:

Operativsystemer: Tre enkle stykker. Del 1: Intro (oversettelse)

Programmet i hovedfunksjonen lager to tråder ved hjelp av kallet pthread_create(). I dette eksemplet kan en tråd betraktes som en funksjon som kjører i samme minneplass sammen med andre funksjoner, med klart mer enn én funksjon som kjører samtidig. I dette eksemplet starter hver tråd og utfører funksjonen worker() som igjen bare øker variabelen,.

La oss kjøre dette programmet med et argument på 1000. Som du kanskje har gjettet, bør resultatet være 2000 fordi hver tråd økte variabelen 1000 ganger. Alt er imidlertid ikke så enkelt. La oss prøve å kjøre programmet med en størrelsesorden flere repetisjoner.

Operativsystemer: Tre enkle stykker. Del 1: Intro (oversettelse)

Ved å legge inn et tall, for eksempel 100000, forventer vi å se utdata som tallet 200000. Men hvis vi kjører tallet 100000 flere ganger, vil vi ikke bare ikke se det riktige svaret, men også få forskjellige feil svar. Svaret ligger i det faktum at for å øke antallet, kreves det tre operasjoner - trekke ut nummeret fra minnet, øke og deretter skrive nummeret tilbake. Siden alle disse instruksjonene ikke utføres atomisk (alt på samme tid), kan merkelige ting som dette skje. Dette problemet kalles i programmering løpstilstand. Når ukjente styrker på et ukjent tidspunkt kan påvirke ytelsen til noen av operasjonene dine.

Kilde: www.habr.com

Legg til en kommentar