Операциялык системалар: үч жеңил даана. 3-бөлүк: Process API (котормо)

Операциялык системаларга киришүү

Эй Хабр! Мен сиздердин назарыңыздарга менин оюмча бир кызыктуу адабияттын бир катар макала-котормолорун келтиргим келет - OSTEP. Бул материалда Unix сыяктуу операциялык системалардын иши, тактап айтканда, процесстер, ар кандай пландоочулар, эс тутум жана заманбап ОСти түзгөн башка ушул сыяктуу компоненттер менен иштөө абдан терең талкууланат. Бардык материалдардын түп нускасын бул жерден көрө аласыз бул жерде. Көңүл буруңуз, котормо профессионалдуу эмес (абдан эркин) жасалган, бирок мен жалпы маанини сактап калдым деп ишенем.

Бул тема боюнча лабораториялык иштерди бул жерден тапса болот:

Башка бөлүктөр:

Ошондой эле менин каналымды текшере аласыз телеграмма =)

Ойготкуч! Бул лекция үчүн лаборатория бар! Кара github

Process API

UNIX системасында процессти түзүүнүн мисалын карап көрөлү. Бул эки системалык чалуу аркылуу ишке ашат айры () и exec().

Call fork()

Операциялык системалар: үч жеңил даана. 3-бөлүк: Process API (котормо)

Fork() чалуу жасаган программаны карап көрөлү. Анын аткарылышынын натыйжасы төмөнкүдөй болот.

Операциялык системалар: үч жеңил даана. 3-бөлүк: Process API (котормо)

Биринчиден, биз main() функциясына кирип, сапты экранга басып чыгарабыз. Сапта оригиналда аталган процесстин идентификатору бар PID же процесстин идентификатору. Бул идентификатор UNIXте процесске кайрылуу үчүн колдонулат. Кийинки команда fork() дегенди чакырат. Бул учурда, процесстин дээрлик так көчүрмөсү түзүлөт. ОС үчүн системада иштеп жаткан бир эле программанын 2 көчүрмөсү бар окшойт, ал өз кезегинде fork() функциясынан чыгат. Жаңы түзүлгөн бала процесси (аны түзгөн ата-энелик процесске карата) мындан ары main() функциясынан баштап аткарылбайт. Бала процесси ата-энелик процесстин так көчүрмөсү эмес экенин эстен чыгарбоо керек, анын өзүнүн дарек мейкиндиги, өзүнүн регистрлери, аткарылуучу инструкциялар үчүн өзүнүн көрсөткүчү жана башкалар бар; Ошентип, fork() функциясынын чакыруучусуна кайтарылган маани башкача болот. Атап айтканда, ата-эне процесси кайтаруу катары бала процессинин PID маанисин алат, ал эми бала 0гө барабар маанини алат. Бул кайтаруу коддорун колдонуу менен сиз процесстерди бөлүп, алардын ар бирин өз ишин аткарууга мажбурлай аласыз. . Бирок бул программанын аткарылышы так аныкталган эмес. 2 процесске бөлүнгөндөн кийин ОС аларды көзөмөлдөп, ошондой эле иштерин пландай баштайт. Эгерде бир ядролуу процессордо аткарылса, процесстердин бири, бул учурда ата-эне, ишин улантат, андан кийин бала процесс башкарууну алат. Кайра иштетүүдө кырдаал башкача болушу мүмкүн.

Чалуу күтүү()

Операциялык системалар: үч жеңил даана. 3-бөлүк: Process API (котормо)

Төмөнкү программаны карап көрөлү. Бул программада чакыруунун болушуна байланыштуу күтө () Ата-эне процесси ар дайым бала процессинин аягына чыгышын күтөт. Бул учурда, биз экранда катуу аныкталган текст чыгарууну алабыз

Операциялык системалар: үч жеңил даана. 3-бөлүк: Process API (котормо)

exec() чалуу

Операциялык системалар: үч жеңил даана. 3-бөлүк: Process API (котормо)

Кыйынчылыкты карап көрөлү exec(). Бул системалык чалуу биз такыр башка программаны иштеткибиз келгенде пайдалуу. Мына биз чакырабыз execvp() сөздү эсептөө программасы болгон wc программасын иштетүү. exec() чакырылганда эмне болот? Бул чакыруу аткарылуучу файлдын атын жана кээ бир параметрлерди аргумент катары өткөрүп берет. Андан кийин бул аткарылуучу файлдан код жана статикалык маалыматтар жүктөлөт жана коду бар өзүнүн сегменти кайра жазылат. Стек жана үймөк сыяктуу эс тутумдун калган аймактары кайра инициализацияланат. Андан кийин ОС жөн гана аргументтердин топтомун өткөрүп, программаны аткарат. Ошентип, биз жаңы процессти түзгөн жокпуз, биз жөн гана учурда иштеп жаткан программаны башка иштеп жаткан программага өзгөрттүк. Тукумда exec() чалуу аткарылгандан кийин, баштапкы программа такыр иштебей калгандай көрүнөт.

Бул баштоо татаалдыгы Unix кабыгы үчүн толугу менен нормалдуу болуп саналат жана ал кабыкчага чалуудан кийин кодду аткарууга мүмкүндүк берет айры (), бирок чалуу алдында exec(). Мындай коддун мисалы, кабык чөйрөсүн ишке киргизүүдөн мурун, ишке ашырылып жаткан программанын муктаждыктарына ылайыкташтыруу болуп саналат.

жумуртканын кабыгы - жөн гана колдонуучу программасы. Ал сизге чакыруу линиясын көрсөтүп, ага бир нерсе жазууну күтөт. Көпчүлүк учурларда, эгер сиз ал жерге программанын атын жазсаңыз, кабык анын жайгашкан жерин таап, fork() ыкмасын чакырып, анан жаңы процессти түзүү үчүн exec() түрүн чакырып, анын жардамы менен бүткүчө күтөт. wait() чалуу. Бала процесси чыкканда, кабык wait() чакыруусунан кайтып келип, кайра чакырууну басып чыгарат жана кийинки буйруктун киргизилишин күтөт.

fork() & exec() бөлүү кабыкчага төмөнкү нерселерди аткарууга мүмкүндүк берет, мисалы:
wc файл > new_file.

Бул мисалда, wc программасынын чыгарылышы файлга багытталат. Кабактын буга жетишүү жолу абдан жөнөкөй - чалуудан мурун бала процессин түзүү exec(), кабык стандарттык чыгарууну жаап, файлды ачат жаңы файл, ошентип, андан ары иштеп жаткан программанын бардык чыгарылышы wc экрандын ордуна файлга багытталат.

Unix түтүгү окшош жол менен ишке ашырылат, алар pipe() чалуу колдонгон айырмасы менен. Бул учурда процесстин чыгуу агымы ядродо жайгашкан түтүк кезеги менен туташтырылат, ага башка процесстин кириш агымы кошулат.

Source: www.habr.com

Комментарий кошуу