Bedryfstelsels: Drie maklike stukke. Deel 3: Proses API (vertaling)

Inleiding tot bedryfstelsels

Haai Habr! Ek wil graag 'n reeks artikels-vertalings van een interessante literatuur na my mening onder u aandag bring - OSTEP. Hierdie materiaal bespreek redelik diep die werk van unix-agtige bedryfstelsels, naamlik werk met prosesse, verskeie skeduleers, geheue en ander soortgelyke komponente waaruit 'n moderne bedryfstelsel bestaan. Jy kan die oorspronklike van alle materiaal hier sien hier. Neem asseblief kennis dat die vertaling onprofessioneel (heel vrylik) gemaak is, maar ek hoop ek het die algemene betekenis behou.

Laboratoriumwerk oor hierdie onderwerp kan hier gevind word:

Ander dele:

Jy kan ook na my kanaal kyk by telegram =)

Alarm! Daar is 'n laboratorium vir hierdie lesing! Kyk github

Proses API

Kom ons kyk na 'n voorbeeld van die skep van 'n proses in 'n UNIX-stelsel. Dit gebeur deur twee stelseloproepe vurk () и exec().

Oproepvurk()

Bedryfstelsels: Drie maklike stukke. Deel 3: Proses API (vertaling)

Oorweeg 'n program wat 'n fork() oproep maak. Die resultaat van die uitvoering daarvan sal soos volg wees.

Bedryfstelsels: Drie maklike stukke. Deel 3: Proses API (vertaling)

Eerstens gaan ons die hoof()-funksie in en druk die string na die skerm. Die reël bevat die proses identifiseerder wat in die oorspronklike genoem word PID of proses identifiseerder. Hierdie identifiseerder word in UNIX gebruik om na 'n proses te verwys. Die volgende opdrag sal fork() noem. Op hierdie stadium word 'n byna presiese kopie van die proses geskep. Vir die OS lyk dit of daar 2 kopieë van dieselfde program op die stelsel loop, wat op sy beurt die fork() funksie sal verlaat. Die nuutgeskepte kinderproses (met betrekking tot die ouerproses wat dit geskep het) sal nie meer uitgevoer word nie, vanaf die hoof()-funksie. Daar moet onthou word dat 'n kinderproses nie 'n presiese kopie van die ouerproses is nie; dit het veral sy eie adresruimte, sy eie registers, sy eie wyser na uitvoerbare instruksies, en dies meer. Dus, die waarde wat aan die oproeper van die fork() funksie teruggestuur word, sal anders wees. In die besonder sal die ouerproses die PID-waarde van die kinderproses as 'n opgawe ontvang, en die kind sal 'n waarde gelyk aan 0 ontvang. Deur hierdie terugstuurkodes te gebruik, kan jy dan prosesse skei en elkeen dwing om sy eie werk te doen . Die uitvoering van hierdie program is egter nie streng gedefinieer nie. Nadat dit in 2 prosesse verdeel is, begin die bedryfstelsel om hulle te monitor, sowel as om hul werk te beplan. As dit op 'n enkelkernverwerker uitgevoer word, sal een van die prosesse, in hierdie geval die ouer, aanhou werk, en dan sal die kinderproses beheer ontvang. Wanneer u weer begin, kan die situasie anders wees.

Oproep wag()

Bedryfstelsels: Drie maklike stukke. Deel 3: Proses API (vertaling)

Oorweeg die volgende program. In hierdie program, as gevolg van die teenwoordigheid van 'n oproep wag() Die ouerproses sal altyd wag vir die kinderproses om te voltooi. In hierdie geval sal ons 'n streng gedefinieerde teksuitvoer op die skerm kry

Bedryfstelsels: Drie maklike stukke. Deel 3: Proses API (vertaling)

exec() oproep

Bedryfstelsels: Drie maklike stukke. Deel 3: Proses API (vertaling)

Oorweeg die uitdaging exec(). Hierdie stelseloproep is nuttig wanneer ons 'n heeltemal ander program wil laat loop. Hier sal ons bel execvp() om die wc-program te laat loop wat 'n woordtelprogram is. Wat gebeur wanneer exec() geroep word? Hierdie oproep word die naam van die uitvoerbare lêer en sommige parameters as argumente deurgegee. Waarna die kode en statiese data van hierdie uitvoerbare lêer gelaai word en sy eie segment met die kode oorskryf word. Die oorblywende geheue-areas, soos die stapel en hoop, word herinitialiseer. Daarna voer die bedryfstelsel eenvoudig die program uit en gee dit 'n stel argumente deur. Ons het dus nie 'n nuwe proses geskep nie, ons het eenvoudig die program wat tans loop, omskep in 'n ander lopende program. Nadat die exec()-oproep in die afstammeling uitgevoer is, lyk dit asof die oorspronklike program glad nie geloop het nie.

Hierdie opstartkomplikasie is heeltemal normaal vir 'n Unix-dop, en laat daardie dop toe om kode uit te voer nadat u gebel het vurk (), maar voor die oproep exec(). 'n Voorbeeld van so 'n kode sou wees om die dopomgewing aan te pas by die behoeftes van die program wat geloods word, voordat dit bekendgestel word.

Shell - net 'n gebruikersprogram. Sy wys jou die uitnodigingsreël en wag dat jy iets daarin skryf. In die meeste gevalle, as jy die naam van 'n program daar skryf, sal die dop sy ligging vind, die fork() metode oproep, en dan 'n soort exec() roep om 'n nuwe proses te skep en wag dat dit voltooi is met 'n wag() oproep. Wanneer die kinderproses uitgaan, sal die dop terugkeer van die wait()-oproep en die prompt weer druk en wag vir die volgende opdrag om ingevoer te word.

Die fork() & exec() split laat die dop toe om die volgende dinge te doen, byvoorbeeld:
wc lêer > nuwe_lêer.

In hierdie voorbeeld word die uitvoer van die wc-program na 'n lêer herlei. Die manier waarop die dop dit bereik, is redelik eenvoudig - deur 'n kinderproses te skep voordat u bel exec(), sluit die dop standaarduitvoer en maak die lêer oop nuwe_lêer, dus alle uitset van die verdere lopende program wc sal herlei word na 'n lêer in plaas van 'n skerm.

Unix pyp word op 'n soortgelyke manier geïmplementeer, met die verskil dat hulle 'n pipe()-oproep gebruik. In hierdie geval sal die proses se uitsetstroom gekoppel word aan 'n pyp-tou wat in die kern geleë is, waaraan die insetstroom van 'n ander proses gekoppel sal word.

Bron: will.com

Voeg 'n opmerking