Operaciumoj: Tri Facilaj Pecoj. Parto 2: Abstraktado: Procezo (traduko)

Enkonduko al Operaciumoj

Hej Habr! Mi ŝatus atentigi vin serion da artikoloj-tradukoj de unu interesa literaturo laŭ mi - OSTEP. Ĉi tiu materialo diskutas sufiĉe profunde la laboron de Unikso-similaj operaciumoj, nome, laboro kun procezoj, diversaj planiloj, memoro kaj aliaj similaj komponantoj kiuj konsistigas modernan OS. Vi povas vidi la originalon de ĉiuj materialoj ĉi tie tie. Bonvolu noti, ke la traduko estis farita senprofesie (sufiĉe libere), sed mi esperas, ke mi konservis la ĝeneralan signifon.

Laboratorio pri ĉi tiu temo troveblas ĉi tie:

Aliaj partoj:

Vi ankaŭ povas kontroli mian kanalon ĉe telegramo =)

Ni rigardu la plej fundamentan abstraktadon, kiun la OS provizas al uzantoj: la procezo. La difino de la procezo estas sufiĉe simpla - ĝi estas kuranta programo. La programo mem estas senviva afero situanta sur la disko - ĝi estas aro da instrukcioj kaj eble iuj senmovaj datumoj atendantaj lanĉon. Estas la OS kiu prenas tiujn bajtojn kaj rulas ilin, transformante la programon en ion utilan.
Plej ofte, uzantoj volas ruli pli ol unu programon samtempe, ekzemple, vi povas ruli retumilon, ludon, plurmedian ludilon, tekstredaktilon kaj similajn sur via tekkomputilo. Fakte, tipa sistemo povas ruli dekojn aŭ centojn da procezoj samtempe. Ĉi tiu fakto faciligas la uzadon de la sistemo, vi neniam devas zorgi pri ĉu la CPU estas senpaga, vi nur rulas programojn.

Ĉi tio levas la problemon: kiel provizi la iluzion de multaj CPUoj? Kiel la OS povas krei la iluzion de preskaŭ senfina nombro da CPUoj, eĉ se vi havas nur unu fizikan CPU?

La OS kreas ĉi tiun iluzion per CPU-virtualigo. Komencante unu procezon, poste ĉesigante ĝin, komencante alian procezon, kaj tiel plu, la OS povas konservi la iluzion, ke ekzistas multaj virtualaj CPUoj, kiam fakte estos unu aŭ pluraj fizikaj procesoroj. Ĉi tiu tekniko nomiĝas divido de CPU-resursoj laŭ tempo. Ĉi tiu tekniko permesas al uzantoj ruli tiom da samtempaj procezoj kiom ili deziras. La kosto de ĉi tiu solvo estas rendimento - ĉar se la CPU estas dividita de pluraj procezoj, ĉiu procezo estos procesita pli malrapide.
Por efektivigi CPU-virtualigon, kaj precipe por fari ĝin bone, la OS bezonas kaj malaltnivelan kaj altnivelan subtenon. Malaltnivela subteno estas nomita mekanismoj estas malaltnivelaj metodoj aŭ protokoloj kiuj efektivigas la postulatan parton de la funkcieco. Ekzemplo de tia funkcieco estas kuntekstŝanĝo, kiu donas al la OS la kapablon ĉesigi unu programon kaj ruli alian programon sur la procesoro. Ĉi tiu tempodivido estas efektivigita en ĉiuj modernaj operaciumoj.
Aldone al ĉi tiuj mekanismoj estas iu logiko konstruita en la OS, en la formo de "politikoj". politiko estas certa decida algoritmo por la operaciumo. Tiaj politikoj, ekzemple, decidas kiu programo devus esti lanĉita (el listo de komandoj) unue. Do, ekzemple, ĉi tiu problemo estos solvita per politiko nomita planilo (plana politiko) kaj elektante solvon, ĝi estos gvidata de tiaj datumoj kiel: ekhistorio (kiu programo estis lanĉita la plej longa en la lastaj minutoj), kian ŝarĝon portas ĉi tiu procezo (kiaj specoj de programoj estis lanĉitaj), agado-metrikoj (ĉu la sistemo). estas optimumigita por interaga interagado aŭ por trafluo ) ktp.

Abstraktado: procezo

La abstraktado de funkcianta programo ekzekutita de la operaciumo estas tio, kion ni nomas procezo. Kiel menciite antaŭe, procezo estas simple funkcianta programo, en iu ajn tuja tempodaŭro. Programo per kiu ni povas akiri resumajn informojn el diversaj sistemaj rimedoj, kiujn ĉi tiu programo aliras aŭ tuŝas dum sia ekzekuto.
Por kompreni la komponantojn de la procezo, vi devas kompreni la statojn de la sistemo: kion la programo povas legi aŭ ŝanĝi dum sia funkciado. En ajna momento, vi devas kompreni, kiuj elementoj de la sistemo estas gravaj por la ekzekuto de la programo.
Unu el la evidentaj elementoj de la sistemo deklaras ke la procezo inkluzivas estas memoro. Instrukcioj troviĝas en memoro. La datumoj kiujn la programo legas aŭ skribas ankaŭ troviĝas en memoro. Tiel, la memoro kiun procezo povas trakti (nomita adresspaco) estas parto de la procezo.
Ankaŭ parto de la sistema stato estas registroj. Multaj instrukcioj celas ŝanĝi la valoron de registroj aŭ legi ilian valoron, kaj tiel registroj ankaŭ fariĝas grava parto de la operacio de la procezo.
Oni devas rimarki, ke la maŝina stato ankaŭ formiĝas el iuj specialaj registroj. Ekzemple, IP - instrukcia montrilo — montrilo al la instrukcio, kiun la programo nuntempe plenumas. Estas ankaŭ stakigi montrilon kaj rilata al ĝi kadra montrilo, kiuj estas uzataj por administri: funkcio-parametrojn, lokajn variablojn kaj revenadresojn.
Fine, programoj ofte aliras ROM (nurlega memoro). Ĉi tiu informo de "I/O" (enigo/eligo) devus inkluzivi liston de dosieroj nuntempe malfermitaj de la procezo.

Proceza API

Por plibonigi nian komprenon pri kiel funkcias la procezo, ni studu ekzemplojn de sistemvokoj, kiuj devus esti inkluzivitaj en iu ajn operaciuma interfaco. Ĉi tiuj API-oj estas haveblaj en unu formo aŭ alia en iu ajn OS.

krei (kreado): La OS devas inkluzivi iun metodon, kiu ebligas al vi krei novajn procezojn. Kiam vi enigas komandon en la terminalon aŭ lanĉas aplikaĵon per duobla alklako sur ikono, alvoko estas sendita al la OS por krei novan procezon kaj poste lanĉi la specifitan programon.
Forigi: Ĉar ekzistas interfaco por krei procezon, la OS ankaŭ devus disponigi la kapablon devigi la forigon de procezo. Plej multaj programoj nature komenciĝos kaj finiĝos memstare dum ili funkcias. Alie la uzanto ŝatus povi mortigi ilin kaj tiel interfaco por haltigi la procezon estus utila.
Atendu (atendo): Kelkfoje estas utile atendi ke procezo finiĝos, do kelkaj interfacoj estas provizitaj, kiuj provizas la kapablon atendi.
Misc Kontrolo (diversa kontrolo): Krom mortigi kaj atendi la procezon, ekzistas ankaŭ aliaj diversaj kontrolmetodoj. Ekzemple, la plej multaj operaciumoj disponigas la kapablon frostigi procezon (ĉesigi ĝian ekzekuton dum certa periodo) kaj tiam rekomenci ĝin (daŭrigi ekzekuton)
Statuso (ŝtato): Estas diversaj interfacoj por akiri iujn informojn pri la stato de procezo, kiel kiom longe ĝi funkcias aŭ en kia stato ĝi estas nuntempe.

Operaciumoj: Tri Facilaj Pecoj. Parto 2: Abstraktado: Procezo (traduko)

Proceza Kreado: Detaloj

Unu el la interesaj aferoj estas kiel ĝuste programoj transformiĝas en procezojn. Precipe kiel la OS prenas kaj kuras la programon. Kiel ĝuste la procezo estas kreita.
Antaŭ ĉio, la OS devas ŝargi la programkodon kaj statikajn datumojn en memoron (en la procezan adresspacon). Programoj estas kutime situantaj sur disko aŭ solidsubstanca disko en iu rulebla formato. Tiel, la procezo de ŝarĝo de programo kaj statikaj datumoj en memoron postulas, ke la OS povu legi tiujn bajtojn el disko kaj meti ilin ie en memoron.

En fruaj operaciumoj, la ŝarĝa procezo estis farita fervore, kio signifas, ke la tuta kodo estis ŝarĝita en memoron antaŭ ol la programo estis lanĉita. Modernaj operaciumoj faras tion pigre, tio estas, ŝarĝante pecojn de kodo aŭ datumoj nur kiam la programo postulas ilin dum sia ekzekuto.

Post kiam la kodo kaj statikaj datumoj estas ŝarĝitaj en OS-memoron, estas kelkaj pliaj aferoj, kiuj devas esti faritaj antaŭ ol la procezo povas funkcii. Iom da memoro devas esti asignita por la stako. Programoj uzas la stakon por lokaj variabloj, funkcioparametroj kaj revenadresoj. La OS asignas ĉi tiun memoron kaj donas ĝin al la procezo. La stako ankaŭ povas esti asignita kun kelkaj argumentoj, specife ĝi plenigas la parametrojn de la funkcio main(), ekzemple kun tabelo de argc kaj argv.

La operaciumo ankaŭ povas asigni iom da memoro al la programa amaso. La amaso estas uzata de programoj por eksplicite peti dinamike asignitajn datenojn. Programoj petas ĉi tiun spacon per vokado de la funkcio malloc () kaj purigas ĝin eksplicite per vokado de la funkcio senpaga (). La amaso estas bezonata por datumstrukturoj kiel ekzemple ligitaj folioj, hashtabeloj, arboj kaj aliaj. Komence, malgranda kvanto da memoro estas asignita al la amaso, sed kun la tempo, dum la programo funkcias, la amaso povas peti pli da memoro per la biblioteko API voko malloc(). La operaciumo estas implikita en la procezo de asigni pli da memoro por helpi kontentigi ĉi tiujn vokojn.

La operaciumo ankaŭ plenumos komencajn taskojn, precipe tiujn rilatajn al I/O. Ekzemple, en UNIX-sistemoj, ĉiu procezo defaŭlte havas 3 malfermitajn dosierpriskribilojn, por norma enigo, eligo kaj eraro. Ĉi tiuj teniloj permesas al programoj legi enigaĵon de la terminalo kaj ankaŭ montri informojn sur la ekrano.

Tiel, ŝarĝante kodon kaj senmovajn datumojn en memoron, kreante kaj inicialigante la stakon, kaj farante alian laboron rilatan al plenumado de I/O-taskoj, la OS preparas la scenejon por la procezo por ekzekuti. Fine, restas unu lasta tasko: ruli la programon tra ĝia enirpunkto, nomata ĉef() funkcio. Ekzekutante la ĉef() funkcion, la OS transdonas CPU-kontrolon al la nove kreita procezo, tiel la programo komencas ekzekuti.

Proceza stato

Nun kiam ni iom komprenas, kio estas procezo kaj kiel ĝi estas kreita, ni listigu la procezŝtatojn en kiuj ĝi povas esti. En ĝia plej simpla formo, procezo povas esti en unu el ĉi tiuj statoj:
kurante. Dum kurado, la procezo funkcias per la procesoro. Ĉi tio signifas, ke instrukcioj estas ekzekutitaj.
preta. En la preta stato, la procezo estas preta por funkcii, sed ial la OS ne plenumas ĝin je la specifita tempo.
Blokitaj. En la blokita stato, procezo faras iujn operaciojn, kiuj malhelpas ĝin esti preta por efektivigi ĝis iu evento okazas. Unu ofta ekzemplo estas kiam procezo iniciatas IO-operacion, ĝi iĝas blokita tiel ke iu alia procezo povas uzi la procesoron.

Operaciumoj: Tri Facilaj Pecoj. Parto 2: Abstraktado: Procezo (traduko)

Vi povas imagi ĉi tiujn statojn en formo de grafeo. Kiel ni povas vidi en la bildo, la proceza stato povas ŝanĝiĝi inter RUNNING kaj PRETA laŭ la bontrovo de la OS. Kiam la stato de procezo ŝanĝiĝas de PRETA al RUNNING, tio signifas, ke la procezo estis planita. En la kontraŭa direkto - forigita de la aranĝo. En la momento kiam procezo fariĝas BLOKITA, ekzemple, mi komencas IO-operacion, la OS konservos ĝin en ĉi tiu stato ĝis iu evento okazos, ekzemple la kompletiĝo de IO. ĉi-momente la transiro al la stato PRETA kaj eble tuj al la stato RUNNING se la OS decidas tion.
Ni rigardu ekzemplon de kiel du procezoj moviĝas tra ĉi tiuj statoj. Komence, ni imagu, ke ambaŭ procezoj funkcias, kaj ĉiu uzas nur la CPU. En ĉi tiu kazo, iliaj statoj aspektos tiel.

Operaciumoj: Tri Facilaj Pecoj. Parto 2: Abstraktado: Procezo (traduko)

En la sekva ekzemplo, la unua procezo, post iom da tempo kuranta, petas IO kaj eniras la BLOKITAn staton, permesante al alia procezo funkcii (FIG 1.4). La OS vidas, ke procezo 0 ne uzas la CPU kaj komencas procezon 1. Dum procezo 1 funkcias, IO finiĝas kaj la stato de procezo 0 ŝanĝiĝas al PRETA. Fine, procezo 1 finiĝis, kaj post kompletigo, procezo 0 komenciĝas, efektivigas kaj finas sian laboron.

Operaciumoj: Tri Facilaj Pecoj. Parto 2: Abstraktado: Procezo (traduko)

Datuma strukturo

La OS mem estas programo, kaj same kiel ĉiu alia programo, ĝi havas kelkajn ŝlosilajn datumstrukturojn, kiuj konservas diversajn koncernajn informojn. Por spuri la staton de ĉiu procezo, la OS subtenos iujn listo de procezoj por ĉiuj procezoj en la PRETA ŝtato kaj iuj aldonaj informoj por spuri procezojn, kiuj nuntempe funkcias. Ankaŭ, la OS devus monitori blokitajn procezojn. Post kiam IO estas kompletigita, la OS devas veki la postulatan procezon kaj meti ĝin en staton pretan por funkcii.

Ekzemple, la OS devas konservi la staton de la procesoraj registroj. En la momento, la procezo ĉesas, la stato de la registroj estas konservita en la adresspaco de la procezo, kaj en la momento, kiam ĝia funkciado daŭras, la valoroj de la registroj estas restarigitaj kaj tiel daŭrigas la ekzekuton de ĉi tiu procezo.

Krom pretaj, blokitaj, kurantaj ŝtatoj, ekzistas iuj aliaj ŝtatoj. Foje, en la momento de kreado, procezo povas esti en la INIT-stato. Fine, procezo povas esti metita en la FINAN staton kiam ĝi jam finiĝis, sed ĝiaj informoj ankoraŭ ne estis purigitaj. Sur UNIX-sistemoj ĉi tiu stato estas nomita zombia procezo. Ĉi tiu stato estas utila por kazoj kie gepatra procezo volas scii la revenkodon de infano, ekzemple, kutime 0 signalas sukceson kaj 1 eraron, sed programistoj povas elsendi kromajn produktaĵkodojn por signali malsamajn problemojn. Kiam la gepatra procezo finiĝas, ĝi faras finan sistemvokon, kiel wait(), por atendi ke la infana procezo finiĝos kaj signali al la OS, ke ĝi povas forigi ajnajn datumojn asociitajn kun la finita procezo.

Operaciumoj: Tri Facilaj Pecoj. Parto 2: Abstraktado: Procezo (traduko)

Ĉefaj punktoj de la prelego:

procezo — la ĉefa abstraktado de funkcianta programo en la OS. En iu antaŭfiksita tempo, procezo povas esti priskribita memstare stato: la enhavo de memoro en ĝia adresspaco, la enhavo de procesorregistroj, inkluzive de instrukcimontrilo kaj stakmontrilo, kaj IO-informoj, kiel ekzemple malfermaj dosieroj estantaj legitaj aŭ skribitaj.
Proceza API konsistas el alvokoj kiujn programoj povas fari al procezoj. Tipe ĉi tiuj estas krei, forigi aŭ aliajn vokojn.
● La procezo estas en unu el multaj statoj, inkluzive de kurado, preta, blokita. Diversaj eventoj kiel planado, esceptoj de planado aŭ atendoj povas ŝanĝi la staton de procezo de unu al alia.
Proceza listo enhavas informojn pri ĉiuj procezoj en la sistemo. Ĉiu eniro en ĝi nomiĝas proceza kontrola bloko, kiu fakte estas strukturo, kiu enhavas ĉiujn necesajn informojn pri specifa procezo. 

fonto: www.habr.com

Aldoni komenton