Sissejuhatus operatsioonisĂŒsteemidesse
Tere, Habr! Soovin esitleda teile huvitavate artiklite tĂ”lgitud seeriat â OSTEP. KĂ€esolevas materjalis uuritakse sĂŒgavalt unix-laadsete operatsioonisĂŒsteemide toimimist, nimelt â protsesside, erinevate planeerijate, mĂ€lu ja teiste sarnaste komponentide töötamist, mis koosnevad kaasaegsest operatsioonisĂŒsteemist. KĂ”iki materjale saate nĂ€ha siin . Palun arvestage, et tĂ”lge on tehtud mitteprofessionaalselt (piisavalt vaba), kuid loodan, et ĂŒldine mĂ”te on sĂ€ilinud.
KÀesoleva aine laboritöid saab leida siit:
Teised osad:
Ja vĂ”ite ka kĂŒlastada minu kanalit =)
HĂ€ire! selle loengu jaoks on labor! vaata
Process API
Vaatame nĂ€idet protsessi loomise kohta UNIX sĂŒsteemis. See toimub kahe sĂŒsteemikĂ”ne kaudu fork() ja exec().
Fork() kÔne

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

Esiteks siseneme funktsiooni main() ja kuvame ekraanile stringi. String sisaldab protsessi identifikaatori, mis originaalis nimetatakse PID vĂ”i protsessi identifikaator. Seda identifikaatorit kasutatakse UNIXis protsessiga suhtlemiseks. JĂ€rgmise kĂ€sklusega kutsub fork() esile. Sel ajahetkel luuakse praktiliselt tĂ€pne koopia protsessist. OperatsioonisĂŒsteemile nĂ€eb see vĂ€lja nii, et sĂŒsteemis on kĂ€ivitunud nagu 2 koopiat samast programmist, mis omakorda vĂ€ljuvad fork() funktsioonist. Uuesti loodud protsess-tĂŒtar (seoses tema loojaga, protsess-ema) ei hakka enam tĂ€itma, alustades funktsioonist main(). Tuleb meeles pidada, et protsess-tĂŒtar ei ole tĂ€pne koopia protsess-ema, eelkĂ”ige on tal oma aadressiruumi, oma registrid, oma nĂ€itaja tĂ€idetavatele juhistele ja nii edasi. Seega, vÀÀrtus, mis suunajale fork() funktsiooni tagastatakse, on erinev. EelkĂ”ige saab protsess-ema tagasivÀÀrtuseks lapse protsessi PID vÀÀrtuse, samas kui laps saab vÀÀrtuse, mis on vĂ”rdne 0. Nende tagasivÀÀrtustega saab hiljem eristada protsesse ja sundida igaĂŒht neist tĂ€itma oma tööd. Samas ei ole antud programmi tĂ€itmine rangelt mÀÀratletud. PĂ€rast kahe protsessi vahel jagamist hakkab operatsioonisĂŒsteem neid jĂ€lgima ja planeerima nende tööd. Ăksikesituatsioonis jĂ€tkab töö tegemist ĂŒks protsess, antud juhul â ema, ning seejĂ€rel vĂ”tab juhtimise endale protsess-tĂŒtar. Taas kĂ€ivitamisel vĂ”ib olukord kujuneda teisiti.
wait() kÔne

Vaatame jĂ€rgmist programmi. Selles programmis tĂ€nu wait() kĂ”ne olemasolule wait() protsess-ema ootab alati protsess-tĂŒtar lĂ”petamist. Sel juhul saame rangelt mÀÀratletud vĂ€ljundi ekraanile

exec() kÔne

Vaatame exec() kutsumist. exec()See sĂŒsteemikĂ”ne on kasulik, kui soovime kĂ€ivitada tĂ€iesti teise programmi. Siin kutsume esile execvp() wc programmi kĂ€ivitamiseks, mis on sĂ”nade loendamise programm. Mis siis toimub, kui kutsutakse exec()? Sellesse kutse antakse argumendina tĂ€idetava faili nimi ja mĂ”ned parameetrid. PĂ€rast seda laaditakse kood ja staatilised andmed sellest kĂ€itatavast failist ja asendatakse oma koodisegment. ĂlejÀÀnud mĂ€lupiirkonnad, nagu Ă”iguste ja kuhja, lĂ€htestatakse. PĂ€rast seda tegeleb opsĂŒsteem lihtsalt programmi kĂ€ivitamisega, edastades sellele argumendid. Sel viisil ei loonud me uut protsessi, vaid lihtsalt muundasime jooksva programmi teiseks jooksva programmiks. PĂ€rast exec() kutset on jĂ€rglases mulje, et algne programm nagu ei kĂ€ivitunudki.
Selle kĂ€ivitamise keerukus on tĂ€iesti normaalne Unix shell-ĂŒhenduses ja vĂ”imaldab sellel shellil tĂ€ita koodi pĂ€rast kutset fork(), kuid enne kutset exec(). Sellise koodi nĂ€itena vĂ”ib tuua shelli keskkonna kohandamise jooksva programmi vajadustele enne selle otsest kĂ€ivitamist.
Shell â see on lihtsalt kasutaja programm. See nĂ€itab teile kutse rida ja ootab, kuni te sinna midagi kirjutate. Enamikul juhtudel, kui sinna programmimise nime kirjutada, leiab shell selle asukoha, kutsub esile fork() meetodi ja seejĂ€rel, et luua uus protsess, kutsub ta mĂ”nda exec() tĂŒĂŒpi ning ootab selle tĂ€itmise lĂ”petamist wait() kutsega. Kui jĂ€rglase protsess lĂ”petab, naaseb shell wait() kutse lĂ”petamisele ja kuvab jĂ€lle kutse rida, ootades jĂ€rgmise kĂ€su sisestamist.
fork() ja exec() eraldamine vÔimaldab shellil teha jÀrgmisi asju, nÀiteks:
wc file > new_file.
Selles nĂ€ites on wc programmi vĂ€ljund suunatud faili. Viis, kuidas shell seda saavutab, on piisavalt lihtne â protsessi-lapse loomisel ennen kutset exec(), sulgeb shell standardvĂ€ljundvoo ja avab faili new_file, seega suunatakse edasise jooksva programmi kogu vĂ€ljund faili asemel ekraanile. wc Unix pipe
on rakendatud sarnasel viisil, erinevuseks on see, et need kasutavad pipe() kutset. Sel juhul on protsessi vĂ€ljundvoog ĂŒhendatud tuumasse asuva ootequeuesse, millele on ĂŒhendatud teise protsessi sisendvoog. đ„Operating Systems: Three Easy Pieces. Part 3: Process API (tĂ”lge) | ProHoster
Allikas: habr.com
