Оперативни системи: три лака комада. Део 3: Процесни АПИ (превод)

Увод у оперативне системе

Хеј Хабр! Желео бих да вам скренем пажњу на серију чланака-превода једне по мени занимљиве литературе – ОСТЕП. У овом материјалу се прилично дубоко разматра рад оперативних система сличних униксу, односно рад са процесима, разним планерима, меморијом и другим сличним компонентама које чине савремени ОС. Овде можете видети оригинал свих материјала овде. Напомињемо да је превод урађен нестручно (прилично слободно), али се надам да сам задржао опште значење.

Лабораторијски рад на ову тему можете пронаћи овде:

Остали делови:

Такође можете погледати мој канал на telegram =)

Алармни! За ово предавање постоји лабораторија! Погледај гитхуб

Процесни АПИ

Погледајмо пример креирања процеса у УНИКС систему. То се дешава кроз два системска позива виљушка () и екец ().

Цалл форк()

Оперативни системи: три лака комада. Део 3: Процесни АПИ (превод)

Размотрите програм који врши позив форк(). Резултат његовог извршења биће следећи.

Оперативни системи: три лака комада. Део 3: Процесни АПИ (превод)

Пре свега, улазимо у функцију маин() и исписујемо стринг на екрану. Линија садржи идентификатор процеса који се у оригиналу зове ПИД или идентификатор процеса. Овај идентификатор се користи у УНИКС-у за упућивање на процес. Следећа команда ће позвати форк(). У овом тренутку се креира скоро тачна копија процеса. За ОС, изгледа да постоје 2 копије истог програма покренуте на систему, који ће заузврат изаћи из функције форк(). Новокреирани подређени процес (у односу на родитељски процес који га је креирао) се више неће извршавати, почевши од функције маин(). Треба имати на уму да подређени процес није тачна копија родитељског процеса, он има свој адресни простор, своје регистре, свој показивач на извршне инструкције и слично; Дакле, вредност враћена позиваоцу функције форк() ће бити другачија. Конкретно, родитељски процес ће примити ПИД вредност подређеног процеса као поврат, а дете ће добити вредност једнаку 0. Користећи ове повратне кодове, онда можете раздвојити процесе и натерати сваки од њих да ради свој посао . Међутим, извршење овог програма није стриктно дефинисано. Након поделе на 2 процеса, ОС почиње да их прати, као и да планира њихов рад. Ако се изврши на процесору са једним језгром, један од процеса, у овом случају родитељски, наставиће да ради, а потом ће надређени процес добити контролу. Приликом поновног покретања, ситуација може бити другачија.

Позив чекај()

Оперативни системи: три лака комада. Део 3: Процесни АПИ (превод)

Размотрите следећи програм. У овом програму, због присуства позива чекати() Родитељски процес ће увек чекати да се доврши процес детета. У овом случају, добићемо стриктно дефинисан текстуални излаз на екрану

Оперативни системи: три лака комада. Део 3: Процесни АПИ (превод)

екец() позив

Оперативни системи: три лака комада. Део 3: Процесни АПИ (превод)

Размотрите изазов екец (). Овај системски позив је користан када желимо да покренемо потпуно другачији програм. Овде ћемо позвати екецвп() да покренете вц програм који је програм за бројање речи. Шта се дешава када се позове екец()? Овом позиву се као аргументи прослеђују име извршне датотеке и неки параметри. Након тога се код и статички подаци из ове извршне датотеке учитавају и њен сопствени сегмент са кодом се преписује. Преостале меморијске области, као што су стек и гомила, се поново иницијализују. Након тога ОС једноставно извршава програм, прослеђујући му скуп аргумената. Дакле, нисмо креирали нови процес, већ смо једноставно трансформисали тренутно покренути програм у други покренути програм. Након извршења екец() позива у потомку, изгледа као да се оригинални програм уопште није покренуо.

Ова компликација при покретању је потпуно нормална за Уник шкољку и омогућава тој љусци да изврши код након позива виљушка (), али пре позива екец (). Пример таквог кода би био прилагођавање окружења љуске потребама програма који се покреће, пре него што се покрене.

Граната - само кориснички програм. Она вам показује линију позивнице и чека да у њој нешто напишете. У већини случајева, ако тамо упишете име програма, љуска ће пронаћи његову локацију, позвати методу форк(), а затим позвати неки тип екец() да креира нови процес и сачекати да се заврши помоћу чекај() позив. Када подређени процес изађе, љуска ће се вратити из чекања() позива и поново одштампати промпт и сачекати да се унесе следећа команда.

Форк() & екец() подела омогућава љусци да уради следеће ствари, на пример:
вц датотека > нова_датотека.

У овом примеру, излаз вц програма је преусмерен на датотеку. Начин на који љуска то постиже је прилично једноставан - креирањем подређеног процеса пре позивања екец (), љуска затвара стандардни излаз и отвара датотеку нова_датотека, дакле, сав излаз из даљег покренутог програма wc биће преусмерени на датотеку уместо на екран.

Уник пипе имплементирани су на сличан начин, с том разликом што користе позив пипе(). У овом случају, излазни ток процеса ће бити повезан са цевним редом који се налази у језгру, на који ће бити повезан улазни ток другог процеса.

Извор: ввв.хабр.цом

Додај коментар