Operační systémy: Tři snadné kusy. Část 3: Process API (překlad)

Úvod do operačních systémů

Čau Habr! Rád bych vás upozornil na sérii článků-překladů jedné dle mého názoru zajímavé literatury - OSTEP. Tento materiál poměrně hluboce pojednává o práci unixových operačních systémů, konkrétně o práci s procesy, různými plánovači, pamětí a dalšími podobnými součástmi, které tvoří moderní OS. Originál všech materiálů si můžete prohlédnout zde zde. Upozorňuji, že překlad byl proveden neprofesionálně (zcela volně), ale doufám, že jsem zachoval obecný význam.

Laboratorní práce na toto téma naleznete zde:

Ostatní části:

Můžete se také podívat na můj kanál na telegram =)

Poplach! Pro tuto přednášku existuje laboratoř! Dívej se github

Procesní API

Podívejme se na příklad vytvoření procesu v systému UNIX. Děje se tak prostřednictvím dvou systémových volání Vidlička() и exec().

Call fork()

Operační systémy: Tři snadné kusy. Část 3: Process API (překlad)

Představte si program, který volá fork(). Výsledek jeho provedení bude následující.

Operační systémy: Tři snadné kusy. Část 3: Process API (překlad)

Nejprve zadáme funkci main() a vytiskneme řetězec na obrazovku. Řádek obsahuje identifikátor procesu, který se v originále nazývá PID nebo identifikátor procesu. Tento identifikátor se v UNIXu používá k odkazování na proces. Další příkaz zavolá fork(). V tomto okamžiku je vytvořena téměř přesná kopie procesu. Pro OS to vypadá, že v systému běží 2 kopie stejného programu, což zase ukončí funkci fork(). Nově vytvořený podřízený proces (ve vztahu k nadřazenému procesu, který jej vytvořil) již nebude prováděn, počínaje funkcí main(). Je třeba mít na paměti, že podřízený proces není přesnou kopií nadřazeného procesu, zejména má svůj vlastní adresní prostor, své vlastní registry, svůj vlastní ukazatel na spustitelné instrukce a podobně. Hodnota vrácená volajícímu funkce fork() tedy bude jiná. Konkrétně nadřazený proces obdrží hodnotu PID podřízeného procesu jako návrat a podřízený proces obdrží hodnotu rovnou 0. Pomocí těchto návratových kódů pak můžete oddělit procesy a přinutit každý z nich, aby dělal svou vlastní práci . Provádění tohoto programu však není přesně definováno. Po rozdělení na 2 procesy je OS začne sledovat a také plánovat jejich práci. Pokud je spuštěn na jednojádrovém procesoru, jeden z procesů, v tomto případě nadřazený, bude pokračovat v práci a potom získá řízení podřízený proces. Při restartu může být situace jiná.

Čekání na hovor()

Operační systémy: Tři snadné kusy. Část 3: Process API (překlad)

Zvažte následující program. V tomto programu kvůli přítomnosti hovoru Počkejte() Nadřazený proces bude vždy čekat na dokončení podřízeného procesu. V tomto případě dostaneme na obrazovku striktně definovaný textový výstup

Operační systémy: Tři snadné kusy. Část 3: Process API (překlad)

volání exec().

Operační systémy: Tři snadné kusy. Část 3: Process API (překlad)

Zvažte výzvu exec(). Toto systémové volání je užitečné, když chceme spustit úplně jiný program. Tady si zavoláme execvp() ke spuštění programu wc, což je program pro počítání slov. Co se stane, když se zavolá exec()? Tomuto volání je předán název spustitelného souboru a některé parametry jako argumenty. Poté je načten kód a statická data z tohoto spustitelného souboru a jeho vlastní segment s kódem je přepsán. Zbývající oblasti paměti, jako je zásobník a halda, jsou znovu inicializovány. Poté OS jednoduše spustí program a předá mu sadu argumentů. Nevytvářeli jsme tedy nový proces, jednoduše jsme transformovali aktuálně běžící program na jiný běžící program. Po provedení volání exec() v potomkovi to vypadá, jako by původní program vůbec neběžel.

Tato spouštěcí komplikace je pro unixový shell zcela normální a umožňuje tomuto shellu spustit kód po zavolání Vidlička(), ale před hovorem exec(). Příkladem takového kódu může být přizpůsobení prostředí shellu potřebám spouštěného programu před jeho spuštěním.

Skořápka - pouze uživatelský program. Ukáže vám řádek s pozvánkou a čeká, až do něj něco napíšete. Ve většině případů, když tam napíšete název programu, shell najde jeho umístění, zavolá metodu fork() a pak zavolá nějaký typ exec() pro vytvoření nového procesu a počká na jeho dokončení pomocí čekejte() volání. Když podřízený proces skončí, shell se vrátí z volání wait() a znovu vytiskne výzvu a počká na zadání dalšího příkazu.

Rozdělení fork() & exec() umožňuje shellu dělat následující věci, například:
wc soubor > nový_soubor.

V tomto příkladu je výstup programu wc přesměrován do souboru. Způsob, jakým toho shell dosáhne, je poměrně jednoduchý – vytvořením podřízeného procesu před voláním exec(), shell zavře standardní výstup a otevře soubor nový soubor, tedy veškerý výstup z dále běžícího programu wc bude přesměrován do souboru místo na obrazovku.

Unixová trubka jsou implementovány podobným způsobem, s tím rozdílem, že používají volání pipe(). V tomto případě bude výstupní proud procesu připojen k frontě potrubí umístěné v jádře, ke které bude připojen vstupní proud jiného procesu.

Zdroj: www.habr.com

Přidat komentář