Operating Systems: Three Easy Pieces. Part 2: Абстракцыя: Працэс (пераклад)

Увядзенне ў аперацыйныя сістэмы

Прывітанне, Хабр! Жадаю прадставіць вашай увазе серыю артыкулаў-перакладаў адной цікавай на мой погляд літаратуры - OSTEP. У гэтым матэрыяле разглядаецца досыць глыбока праца unix-падобных аперацыйных сістэм, а менавіта - праца з працэсамі, рознымі планавальнікамі, памяццю і іншымі падобнымі кампанентамі, якія складаюць сучасную АС. Арыгінал усіх матэрыялаў вы можаце паглядзець вось тут. Прашу ўлічыць, што пераклад выкананы непрафесійна (дастаткова вольна), але спадзяюся агульны сэнс я захаваў.

Лабараторныя працы па дадзеным прадмеце можна знайсці вось тут:

Іншыя часткі:

А яшчэ можаце зазіраць да мяне на канал у тэлеграм =)

Разгледзім найболей фундаментальную абстракцыю, якую АС падае карыстачам: працэс. Вызначэнне працэсу даволі проста - гэта працавальная праграма. Праграма сама па сабе з'яўляецца знежывелай рэччу, якая размяшчаецца на дыску - гэта набор інструкцый і магчыма нейкіх статычных дадзеных, якія чакаюць моманту запуску. Менавіта АС бярэ гэтыя байты і запускае іх, пераўтвору праграму ў нешта карыснае.
Часцей за ўсё карыстачы жадаюць запускаць больш адной праграмы адначасова, напрыклад вы можаце запусціць на вашым наўтбуку браўзэр, гульню, медыяплэер, тэкставы рэдактар ​​і таму падобнае. Фактычна тыповая сістэма можа запускаць дзясяткі і сотні працэсаў адначасова. Гэты факт робіць сістэму прасцейшы ў выкарыстанні, вам ніколі не даводзіцца турбавацца аб тым, ці вольны CPU, вы проста запускаеце праграмы.

Адгэтуль выцякае праблема: як забяспечыць ілюзію мноства CPU? Як АС стварыць ілюзію практычна бясконцай колькасці CPU, нават калі ў вас усяго адзін фізічны CPU?

АС стварае гэтую ілюзію з дапамогай віртуалізацыі CPU. Запускаючы адзін працэс, затым спыняючы яго, запускаючы іншы працэс і гэтак далей, АС можа падтрымліваць ілюзію таго, што існуе мноства віртуальных CPU, хоць фактычна гэта будзе адзін ці некалькі фізічных працэсараў. Такая тэхніка называецца падзел рэсурсаў CPU па часе. Гэтая тэхніка дазваляе карыстальнікам запускаць столькі адначасовых працэсаў, колькі яны пажадаюць. Коштам такога рашэння з'яўляецца прадукцыйнасць - паколькі калі CPU дзеляць некалькі працэсаў, кожны працэс будзе апрацоўвацца павольней.
Для ўвасаблення віртуалізацыі CPU, а асабліва для таго каб рабіць гэта добра, АС мае патрэбу і ў нізкаўзроўневай і ў высокаўзроўневай падтрымцы. Нізкаўзроўневая падтрымка называецца механізмамі - гэта нізкаўзроўневыя метады або пратаколы, якія рэалізуюць патрэбную частку функцыяналу. Прыклад такога функцыяналу - кантэкстнае пераключэнне, якое дае АС магчымасць спыняць адну праграму і запускаць на працэсары іншую праграму. Такі падзел па часе рэалізавана ва ўсіх сучасных АС.
На вяршыні гэтых механізмаў размяшчаецца некаторая логіка, закладзеная ў АС, у форме "палітык". Палітыка - гэта некаторы алгарытм прыняцця рашэння аперацыйнай сістэмай. Такія палітыкі, напрыклад, вырашаюць, якую праграму трэба запускаць (са спісу каманд) у першую чаргу. Так, напрыклад, дадзеную задачу вырашыць палітыка, якая называецца планавальнік (scheduling policy) і пры выбары рашэння будзе кіравацца такімі дадзенымі як: гісторыя запуску (якая праграма была запушчана даўжэй за ўсіх за апошнюю хвіліну), якую нагрузку ажыццяўляе дадзены працэс (якія тыпы праграм былі запушчаны), метрыкі прадукцыйнасці (ці аптымізавана сістэма для інтэрактыўнага ўзаемадзеяння або для прапускной здольнасці ) і гэтак далей.

Абстракцыя: працэс

Абстракцыя працавальнай праграмы, якая выконваецца аперацыйнай сістэмай гэта тое, што мы завём працэс. Як ужо было сказана раней працэс - гэта проста працуе праграма, у любы маментальны прамежак часу. Праграма з дапамогай якой мы можам атрымаць сумарную інфармацыю з розных рэсурсаў сістэмы, і да якіх звяртаецца ці якія гэтая праграма закранае ў працэсе свайго выканання.
Для разумення складнікаў працэсу трэба разумець стан сістэмы: што праграма можа счытваць ці змяняць падчас сваёй працы. У любы момант часу трэба разумець, якія элементы сістэмы важны для выканання праграмы.
Адным з відавочных элементаў стану сістэмы, якія ўключае ў сябе працэс - гэта памяць. Інструкцыі размяшчаюцца ў памяці. Дадзеныя, якія праграма чытае ці піша таксама, размяшчаюцца ў памяці. Такім чынам, памяць, якую працэс можа адрасаваць (так званая адрасная прастора) з'яўляецца часткай працэсу.
Таксама часткай стану сістэмы з'яўляюцца рэгістры. Мноства інструкцый накіравана на тое, каб змяніць значэнне рэгістраў або прачытаць іх значэнне і такім чынам рэгістры таксама становяцца важнай часткай працы працэсу.
Варта адзначыць, што стан машыны фармуецца таксама з некаторых спецыяльных рэгістраў. Напрыклад, IP - instruction pointer - паказальнік на інструкцыю, якую праграма выконвае ў бягучы момант. Яшчэ ёсць паказальнік стэка і звязаны з ім frame pointer, якія выкарыстоўваюцца для кіравання: параметрамі функцый, лакальнымі зменнымі і адрасамі звароту.
Нарэшце, праграмы часта звяртаюцца да ПЗУ (пастаяннай запамінальнай прыладзе). Такая інфармацыя аб "I/O" (уводзе-вывадзе) павінна ўключаць у сябе спіс файлаў, адкрытых працэсам у дадзены момант.

Process API

Для таго каб палепшыць разуменні працы працэсу вывучым прыклады сістэмных выклікаў, якія павінны быць уключаны ў любы інтэрфейс аперацыйнай сістэмы. Гэтыя API у тым ці іншым выглядзе даступныя на любой АС.

Ствараць (стварэнне): У АС павінен уваходзіць які або метад, які дазваляе ствараць новы працэсы. Калі вы ўводзіце каманду ў тэрмінал або запускаеце прыкладанне праз падвойны клік па абразку, дасылаецца зварот да АС для стварэння новага працэсу і наступнага запуску паказанай праграмы.
Выдаленне: Калі ёсць інтэрфейс для стварэння працэсу, АС таксама павінна прадастаўляць магчымасць для прымусовага выдалення працэсу. Большасць праграм натуральна будуць запушчаны і завершаны самі па сабе па меры іх выканання. У адваротным выпадку карыстач жадаў бы мець магчымасць забіць іх і такім чынам інтэрфейс для прыпынку працэсу будзе не лішнім.
пачакайце (чаканне): Часам карысна дачакацца завяршэння працэсу, таму забяспечваюцца некаторыя інтэрфейсы якія прадстаўляюць магчымасцю чакання.
Рознае кіраванне (рознае кіраванне): Акрамя забойства і чаканні працэсу яшчэ існуюць іншыя разнастайныя кантралюючыя метады. Напрыклад большасць АС падаюць магчымасць замарозкі працэсу (прыпынак яго выканання на некаторы перыяд) і наступнае аднаўленне (працяг выканання)
Стан (стан): Існуюць розныя інтэрфейсы для атрымання некаторай інфармацыі ён статусе працэсу, такія як працягласць яго працы ці ў якім стане ён зараз знаходзіцца.

Operating Systems: Three Easy Pieces. Part 2: Абстракцыя: Працэс (пераклад)

Стварэнне працэсу: дэталі

Адна з цікавых рэчаў - як жа менавіта праграмы трансфармуюцца ў працэсы. Асабліва, як АС паднімае і запускае праграму. Як канкрэтна ствараецца працэс.
У першую чаргу АС павінна загрузіць код праграмы і статычныя дадзеныя ў памяць (у адрасную прастору працэсу). Праграмы звычайна размяшчаюцца на дыску або цвёрдацельным назапашвальніку ў некаторым выкананым фармаце. Такім чынам, працэс загрузкі праграмы і статычных дадзеных у памяць патрабуе ад АС магчымасці прачытаць гэтыя байты з кружэлкі і размясціць іх дзесьці ў памяці.

У ранніх АС працэс загрузкі выконваўся нецярпліва (eagerly), гэта значыць гэта значыць што код загружаўся ў памяць цалкам да таго як праграма запускалася. Сучасныя АС робяць гэта ляніва (lazily), гэта значыць загружаючы кавалачкі кода ці дадзеных толькі тады, калі яны патрабуюцца праграме падчас яе выканання.

Пасля таго як код і статычныя дадзеныя загружаны ў памяць АС трэба выканаць яшчэ некалькі рэчаў перад тым як запусціць працэс. Некаторая колькасць памяці павінна быць выдзелена пад стэк. Праграмы выкарыстоўваюць стэк для лакальных зменных, параметраў функцый і адрасоў звароту. АС вылучае гэтую памяць і аддае яе працэсу. Стэк таксама можа вылучацца з некаторымі аргументамі, менавіта яна запаўняе параметры функцыі main(), напрыклад масівам argc і argv.

Аперацыйная сістэма можа таксама вылучаць некаторую колькасць памяці пад кучу (heap) праграмы. Куча выкарыстоўваецца праграмамі для відавочна запытаных дынамічна вылучаных дадзеных. Праграмы запытваюць гэтую прастору, выклікаючы функцыю малачок () і відавочна чысціць, выклікаючы функцыю бясплатна(). Куча патрэбна для такіх структур дадзеных як: злучаныя лісты, табліцы хэшаў, дрэвы і іншыя. Спачатку пад кучу вылучаецца невялікая колькасць памяці, але з часам падчас прац праграмы куча можа запытаць большую колькасць памяці, праз бібліятэчны API выклік malloc(). Аперацыйная сістэма залучана ў працэс вылучэння большай колькасці памяці для таго, каб дапамагчы ў задавальненні гэтых выклікаў.

Аперацыйная сістэма таксама будзе выконваць задачы ініцыялізацыі, у прыватнасці тыя, якія адносяцца да ўводу-вываду. Напрыклад, у сістэмах UNIX кожны працэс па змаўчанні мае 3 адчыненых файлавых дэскрыптара, для стандартнага струменя ўводу, высновы і памылак. Гэтыя дэскрыптары дазваляюць праграмам счытваць увод з тэрмінала, а таксама выводзіць інфармацыю на экран.

Такім чынам, загружаючы код і статычныя дадзеныя ў памяць, ствараючы і ініцыялізуючы стэк, а таксама выконваючы іншую працу, якая адносіцца да выканання задач уводу-высновы, АС падрыхтоўвае пляцоўку для выканання працэсу. У рэшце рэшт, застаецца апошняя задача: запусціць на выкананне праграму праз яе кропку ўводу, званую функцыяй main(). Пераходзячы да выканання функцыі main(), АС перадае кіраванне CPU ізноў створанаму працэсу, такім чынам, праграма пачынае выконвацца.

Стан працэсу

Цяпер, калі ў нас ёсць некаторае разуменне, што такое працэс і як ён ствараецца, пералічым станы працэсу, у якіх ён можа знаходзіцца. У самай простай форме працэс можа знаходзіцца ў адным з гэтых станаў:
Праца. У запушчаным стане працэс выконваецца на працэсары. Гэта значыць, што адбываецца выкананне інструкцый.
Гатовы. У стане гатоўнасці працэс гатовы запусціцца, але па нейкіх прычынах АС не выконвае яго ў зададзены момант часу.
Блакаваны. У заблакаваным стане працэс выконвае нейкія аперацыі, якія не даюць яму быць гатовым да выканання да таго часу, пакуль не адбудзецца якая-небудзь падзея. Адзін са звычайных прыкладаў - калі працэс ініцыялізуе аперацыю IO, ён становіцца заблакаваным і такім чынам нейкі іншы працэс можа выкарыстоўваць працэсар.

Operating Systems: Three Easy Pieces. Part 2: Абстракцыя: Працэс (пераклад)

Уявіць сабе гэтыя станы можна ў выглядзе графа. Як мы можам бачыць на малюнку, стан працэсу можа мяняцца паміж RUNNING і READY на меркаванне АС. Калі стан працэсу мяняецца з READY, на RUNNING гэта азначае, што працэс быў запланаваны. У адваротны бок - зняты з планіроўкі. У момант, калі працэс становіцца BLOCKED, напрыклад, ініцыялізую аперацыю IO, АС будзе трымаць яго ў гэтым стане да наступу некаторай падзеі, напрыклад завяршэнне IO. у гэты момант пераход у стан READY і магчыма маментальна ў стан RUNNING, калі так вырашыць АС.
Давайце зірнем на прыклад таго, як два працэсы праходзяць праз гэтыя станы. Для пачатку ўявім, што абодва працэсы запушчаныя, і кожны выкарыстоўвае толькі CPU. У гэтым выпадку, іх станы будуць выглядаць наступным чынам.

Operating Systems: Three Easy Pieces. Part 2: Абстракцыя: Працэс (пераклад)

У наступным прыкладзе першы працэс праз некаторы час працы запытвае IO і пераходзіць у стан BLOCKED, падаючы іншаму працэсу магчымасць запуску (МАЛ 1.4). АС бачыць, што працэс 0 не выкарыстоўвае CPU і запускае працэс 1. Падчас выканання працэсу 1 – IO завяршаецца і статут працэсу 0 змяняецца на READY. Нарэшце працэс 1 завяршыўся, а па ім канчатку працэс 0 запускаецца, выконваецца і сканчае сваю працу.

Operating Systems: Three Easy Pieces. Part 2: Абстракцыя: Працэс (пераклад)

Структура даных

АС сама з'яўляецца праграмай, і таксама як і любая іншая праграма мае некаторыя ключавыя структуры дадзеных, якія адсочваюць разнастайныя рэлевантныя кавалкі інфармацыі. Для адсочвання стану кожнага працэсу ў АС будзе падтрымлівацца некаторы process list для ўсіх працэсаў у стане READY і некаторую дадатковую інфармацыю для адсочвання працэсаў, якія выконваюцца ў бягучы момант. Таксама, АС павінна адсочваць і заблакаваныя працэсы. Пасля завяршэння IO, АС павінна абудзіць патрэбны працэс і перавесці яго ў стан гатоўнасці да запуску.

Так, напрыклад, АС павінна захаваць стан рэгістраў працэсара. У момант прыпынку працэсу стан рэгістраў захоўваецца ў адраснай прасторы працэсу, а ў момант працягу яго працы - аднавіць значэнні рэгістраў і такім чынам працягнуць выкананні гэтага працэсу.

Акрамя станаў ready, blocked, running існуюць яшчэ некаторыя іншыя станы. Часам у момант стварэння працэс можа мець стан INIT. Нарэшце працэс можа быць змешчаны стан FINAL, калі ён ужо завяршыўся, але інфармацыя аб ім яшчэ не вычышчана. У UNIX сістэмах такі стан завецца працэс-зомбі. Гэты стан карысна для выпадкаў калі бацькоўскі працэс жадае пазнаць код звароту нашчадка, напрыклад, звычайна 0 сігналізуе аб паспяховым завяршэнні, а 1 аб памылковым, аднак праграмісты могуць рабіць дадатковыя коды высновы, сігналізуючы аб розных праблемах. Пры завяршэнні працэс-бацька робіць апошні сістэмны выклік, напрыклад wait(), каб дачакацца завяршэння працы працэсу-нашчадка і прасігналізаваць АС аб тым, што можна ачысціць любыя дадзеныя, злучаныя з завершаным працэсам.

Operating Systems: Three Easy Pieces. Part 2: Абстракцыя: Працэс (пераклад)

Ключавыя моманты лекцыі:

працэс - Галоўная абстракцыя працавальнай праграмы ў АС. У любы момант часу працэс можа быць апісаны па ім стану: змесціва памяці ў яго адраснай прасторы, змесціва рэгістраў працэсара, уключаючы instruction pointer і stack pointer таксама інфармацыяй аб IO, напрыклад адчыненымі файламі, якія счытваюцца ці запісваюцца.
Process API складаецца з выклікаў, якія праграмы могуць рабіць у адносінах да працэсаў. Звычайна гэта выклікі стварэння, выдаленні ці іншыя.
● Працэс знаходзіцца ў адным са мноства станаў, уключаючы running, ready, blocked. Розныя падзеі, такія як планіроўка, выключэнне з планіроўкі або чаканні могуць пераводзіць стан працэсу з аднаго ў іншае.
Process list змяшчае інфармацыю аб усіх працэсах у сістэме. Кожны запіс у ім называецца process control block, які ў рэальнасці з'яўляецца структурай, якая змяшчае ўсю неабходную інфармацыю аб канкрэтным працэсе. 

Крыніца: habr.com

Дадаць каментар