Operačné systémy: Tri jednoduché kusy. Časť 3: Process API (preklad)

Úvod do operačných systémov

Čau Habr! Chcel by som vám dať do pozornosti sériu článkov-prekladov jednej podľa mňa zaujímavej literatúry - OSTEP. Tento materiál pomerne hlboko rozoberá prácu operačných systémov podobných unixu, konkrétne prácu s procesmi, rôznymi plánovačmi, pamäťou a inými podobnými komponentmi, ktoré tvoria moderný OS. Originál všetkých materiálov si môžete pozrieť tu tu. Upozorňujem, že preklad bol urobený neprofesionálne (celkom voľne), ale dúfam, že som zachoval všeobecný význam.

Laboratórne práce na túto tému nájdete tu:

Ďalšie časti:

Môžete sa tiež pozrieť na môj kanál na telegram =)

Poplach! Na túto prednášku existuje laboratórium! Pozri github

Process API

Pozrime sa na príklad vytvorenia procesu v systéme UNIX. Deje sa tak prostredníctvom dvoch systémových volaní vidlička() и exec().

Call fork()

Operačné systémy: Tri jednoduché kusy. Časť 3: Process API (preklad)

Predstavte si program, ktorý volá fork(). Výsledok jeho vykonania bude nasledovný.

Operačné systémy: Tri jednoduché kusy. Časť 3: Process API (preklad)

V prvom rade zadáme funkciu main() a vypíšeme reťazec na obrazovku. Riadok obsahuje identifikátor procesu, ktorý sa v origináli nazýva PID alebo identifikátor procesu. Tento identifikátor sa používa v systéme UNIX na označenie procesu. Ďalší príkaz zavolá fork(). V tomto bode sa vytvorí takmer presná kópia procesu. Pre OS to vyzerá tak, že v systéme bežia 2 kópie toho istého programu, ktorý následne ukončí funkciu fork(). Novovytvorený podriadený proces (vo vzťahu k rodičovskému procesu, ktorý ho vytvoril) sa už nebude vykonávať, počnúc funkciou main(). Malo by sa pamätať na to, že podriadený proces nie je presnou kópiou nadradeného procesu, najmä má svoj vlastný adresný priestor, svoje vlastné registre, svoj vlastný ukazovateľ na spustiteľné inštrukcie a podobne. Hodnota vrátená volajúcemu funkcie fork() bude teda iná. Hlavne nadradený proces dostane hodnotu PID podriadeného procesu ako návrat a potomok dostane hodnotu rovnajúcu sa 0. Pomocou týchto návratových kódov potom môžete oddeliť procesy a prinútiť každý z nich, aby vykonal svoju vlastnú prácu . Vykonávanie tohto programu však nie je presne definované. Po rozdelení na 2 procesy ich OS začne sledovať, ako aj plánovať ich prácu. Ak je spustený na jednojadrovom procesore, jeden z procesov, v tomto prípade nadradený, bude pokračovať v práci a potom dostane riadenie podriadený proces. Pri reštarte môže byť situácia iná.

Čakanie na hovor()

Operačné systémy: Tri jednoduché kusy. Časť 3: Process API (preklad)

Zvážte nasledujúci program. V tomto programe kvôli prítomnosti hovoru počkaj () Rodičovský proces bude vždy čakať na dokončenie podriadeného procesu. V tomto prípade dostaneme na obrazovku striktne definovaný textový výstup

Operačné systémy: Tri jednoduché kusy. Časť 3: Process API (preklad)

volanie exec().

Operačné systémy: Tri jednoduché kusy. Časť 3: Process API (preklad)

Zvážte výzvu exec(). Toto systémové volanie je užitočné, keď chceme spustiť úplne iný program. Tu zavoláme execvp() spustiť program wc, čo je program na počítanie slov. Čo sa stane, keď sa zavolá exec()? Tomuto volaniu sa odovzdá názov spustiteľného súboru a niektoré parametre ako argumenty. Potom sa načíta kód a statické údaje z tohto spustiteľného súboru a prepíše sa jeho vlastný segment s kódom. Zvyšné pamäťové oblasti, ako napríklad zásobník a halda, sa znova inicializujú. Potom OS jednoducho spustí program a odovzdá mu sadu argumentov. Nevytvárali sme teda nový proces, jednoducho sme transformovali aktuálne spustený program na iný spustený program. Po vykonaní volania exec() v potomkovi to vyzerá, akoby sa pôvodný program vôbec nespustil.

Táto komplikácia pri spustení je pre unixový shell úplne normálna a umožňuje tomuto shellu spustiť kód po zavolaní vidlička(), ale pred hovorom exec(). Príkladom takéhoto kódu by bolo prispôsobenie prostredia shellu potrebám spúšťaného programu pred jeho spustením.

Mušla - len užívateľský program. Ukáže vám pozývací riadok a čaká, kým doň niečo napíšete. Vo väčšine prípadov, ak tam napíšete názov programu, shell nájde jeho umiestnenie, zavolá metódu fork() a potom zavolá nejaký typ exec() na vytvorenie nového procesu a počká na jeho dokončenie pomocou príkazu počkajte () hovor. Keď sa podriadený proces ukončí, shell sa vráti z volania wait() a znova vytlačí výzvu a počká na zadanie ďalšieho príkazu.

Rozdelenie fork() & exec() umožňuje shellu robiť napríklad tieto veci:
wc súbor > nový_súbor.

V tomto príklade je výstup programu wc presmerovaný do súboru. Spôsob, akým to shell dosiahne, je celkom jednoduchý – vytvorením podriadeného procesu pred volaním exec(), shell zatvorí štandardný výstup a otvorí súbor nový_súbor, teda všetok výstup z ďalšieho spusteného programu wc bude presmerovaný do súboru namiesto obrazovky.

Unixové potrubie sú implementované podobným spôsobom s tým rozdielom, že používajú volanie pipe(). V tomto prípade bude výstupný tok procesu pripojený k potrubnej fronte umiestnenej v jadre, ku ktorej bude pripojený vstupný tok iného procesu.

Zdroj: hab.com

Pridať komentár