Operating Systems: Three Easy Pieces. Part 3: Process API (tÔlge)

Sissejuhatus operatsioonisĂŒsteemidesse

Tere, Habr! Soovin tutvustada teile artiklite seeriat, mis on tĂ”lkinud minu arvates huvitavat kirjandust — OSTEP. Selles materjalis kĂ€sitletakse sĂŒgavalt unix-sarnaste operatsioonisĂŒsteemide toimimist, sealhulgas protsesside, erinevate planeerijate, mĂ€luhalduse ja muude sarnaste komponentide töötamise aspekte, mis moodustavad tĂ€napĂ€eva operatsioonisĂŒsteemi. Originaali kĂ”iki materjale saate vaadata siit: siin. Palun arvestage, et tĂ”lge on tehtud mitteprofessionaalselt (piisavalt vabalt), kuid loodan, et olen pĂ”hisisu sĂ€ilitanud.

Laboritööd selle aine kohta leiate siit:

Teised osad:

Lisaks vÔite minna minu kanalile Telegraam =)

HĂ€ire! selle loenguga on labor! vaata github

Protsessi API

Vaadake nĂ€idet protsessi loomisest UNIX sĂŒsteemis. See toimub kahe sĂŒsteemi kĂ”ne kaudu fork() ja exec().

Kutse fork()

Operating Systems: Three Easy Pieces. Part 3: Process API (tÔlge)

Vaadake programmi, mis kutsub esile fork(). Selle tÀitmise tulemus on jÀrgmine.

Operating Systems: Three Easy Pieces. Part 3: Process API (tÔlge)

Esiteks siseneme funktsiooni main() ja vĂ€lja kirjutame rea ekraanile. Rida sisaldab protsessi identifikaatorit, mida algselt nimetatakse PID vĂ”i protsessi identifikaator. See identifikaator kasutatakse UNIXis, et viidata protsessile. JĂ€rgmise kĂ€suga kutsub kĂ€ivituma funktsioon fork(). Sel hetkel luuakse praktiliselt tĂ€pne koopia protsessist. OperatsioonisĂŒsteemi jaoks nĂ€eb see vĂ€lja nii, et sĂŒsteemis on nagu kaks koopia sama programmiga, mis lĂ”petavad fork() funktsioonist vĂ€ljumise. Uuesti loodud protsess-lapse (seoses selle loonud protsess-vanemaga) ei hakka enam töötama alates funktsioonist main(). Tuleb meeles pidada, et protsess-laps ei ole protsess-vanema tĂ€pne koopia, eelkĂ”ige on tal oma aadressiruum, oma registrid, oma nĂ€idud tĂ€idetavate juhiste jaoks ja nii edasi. Seega tagastatav vÀÀrtus funktsiooni fork() kutse korral on erinev. EelkĂ”ige saab protsess-vanem tagastuseks protsessi lapse PID vÀÀrtuse, samas kui laps saab vÀÀrtuse, mis on vĂ”rdne 0. Nende tagastuskoodide alusel saab hiljem juba eristada protsesse ja sundida igaĂŒht nende tööd tegema. Siiski ei ole selle programmi tĂ€itmine rangelt mÀÀratletud. PĂ€rast kaheks jagunemist jĂ€lgib OS neid ja kavandab nende tööd. ÜhesĂŒdamiku protsessori korral jĂ€tkab töö ĂŒhel protsessil, antud juhul - vanemal, ja seejĂ€rel saab juhtimise protsess-laps. Uue kĂ€ivitamise korral vĂ”ib olukord olla erinev.

Wait() kutse

Operating Systems: Three Easy Pieces. Part 3: Process API (tÔlge)

Vaatame jÀrgmist programmi. Selle programmi puhul, tÀnu kutse olemasolule wait() vanemprotsess ootab alati jÀrglase protsessi lÔpetamist. Sel juhul saame tÀpselt mÀÀratletud vÀljundi ekraanile

Operating Systems: Three Easy Pieces. Part 3: Process API (tÔlge)

Exec() kutse

Operating Systems: Three Easy Pieces. Part 3: Process API (tÔlge)

Vaatame kutset exec(). See sĂŒsteemikutse on kasulik, kui soovime kĂ€ivitada tĂ€iesti teise programmi. Siin kutsume ĂŒles execvp() wc programmi kĂ€ivitamiseks, mis on sĂ”nade loendamise programm. Mida juhtub exec() kutse tegemisel? Sellele kutsele edastatakse argumentidena kĂ€ivitatava faili nimi ja mĂ”ned parameetrid. SeejĂ€rel laaditakse koode ja staatilisi andmeid sellest kĂ€ivitatavast failist ning asendatakse omaenda koodisegment. Muu mĂ€lu, nagu virn ja hunnik, initialiseeritakse uuesti. PĂ€rast seda operatsioonisĂŒsteem lihtsalt tĂ€idab programmi, edastades sellele argumendikomplekti. Seega ei loonud me uut protsessi, vaid muutsime jooksva programmi teiseks jooksvaks programmiks. PĂ€rast exec() kutse tegemist on jĂ€rglasel tunne, et algne programm ei ole ĂŒldse kĂ€ivitatud.

See kÀivitamise keerukus on tÀiesti normaalne Unix shelli jaoks ja vÔimaldab sellel shellil koodi tÀita pÀrast kutset fork(), aga enne kutset exec(). Sellise koodi nÀiteks vÔib olla shelli keskkonna kohandamine kÀivitatava programmi vajaduste jÀrgi, enne selle vahetut kÀivitamist.

Shell — vaid kasutajate rakendus. See kuvab teile kĂ€surea ja ootab, kuni kirjutate sinna midagi. Enamikul juhtudel, kui sinna kirjutada programmi nimi, leiab shell selle asukoha, kutsub esile fork() meetodi, seejĂ€rel kutsub mĂ”ne exec() tĂŒĂŒpi meetodi, et luua uus protsess ja ootab selle tĂ€itmise lĂ”ppemist wait() kutsumisega. Kui alampakett lĂ”petab, naaseb shell wait() kutsumisest ja kuvab uuesti kĂ€surea ning ootab jĂ€rgmise kĂ€su sisestamist.

fork() ja exec() eraldamine vÔimaldab shell'il teha jÀrgmisi asju, nÀiteks:
wc fail > new_file.

Selles nĂ€ites suunatakse wc programmi vĂ€ljund faili. See, kuidas shell seda saavutab, on piisavalt lihtne — enne lapseprotsessi loomist ja kutsumist exec(), sulgeb shell standardse vĂ€ljundvoo ja avab faili new_file, seega suunatakse kogu edaspidi kĂ€ivitava programmi wc vĂ€ljund faili asemel ekraanile.

Unix pipe on realiseeritakse sarnaselt, kuid erinevusega, et nad kasutavad pipe() kutsumist. Sellisel juhul on protsessi vĂ€ljundvoog ĂŒhendatud tuumasse paikneva pipe jĂ€rjekorraga, millele on aga ĂŒhendatud teise protsessi sisendvoog.

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster