Үйлдлийн системүүд: Гурван хялбар хэсэг. 3-р хэсэг: Процессын API (орчуулга)

Үйлдлийн системийн танилцуулга

Хөөе Хабр! Миний бодлоор OSTEP хэмээх нэгэн сонирхолтой уран зохиолын цуврал нийтлэл-орчуулгыг та бүхэнд хүргэхийг хүсч байна. Энэхүү материал нь орчин үеийн үйлдлийн системийг бүрдүүлдэг процесс, төрөл бүрийн хуваарь, санах ой болон бусад ижил төстэй бүрэлдэхүүн хэсгүүдтэй ажиллах unix-тэй төстэй үйлдлийн системүүдийн ажлыг нэлээд гүнзгий авч үздэг. Та бүх материалын эх хувийг эндээс харж болно энд. Орчуулга нь мэргэжлийн бус (нэлээн чөлөөтэй) хийгдсэн гэдгийг анхаарна уу, гэхдээ би ерөнхий утгыг хадгалсан гэдэгт найдаж байна.

Энэ сэдвээр хийсэн лабораторийн ажлыг эндээс харж болно.

Бусад хэсгүүд:

Та мөн миний сувгийг эндээс үзэж болно цахилгаан утас =)

Сэрүүлэг! Энэ лекцэнд зориулсан лаборатори байна! Хараач github

Процессын API

UNIX системд процесс үүсгэх жишээг авч үзье. Энэ нь системийн хоёр дуудлагаар явагддаг сэрээ () и exec().

Дуудлага хийх сэрээ()

Үйлдлийн системүүд: Гурван хялбар хэсэг. 3-р хэсэг: Процессын API (орчуулга)

Fork() дуудлага хийдэг программыг авч үзье. Түүний гүйцэтгэлийн үр дүн дараах байдалтай байна.

Үйлдлийн системүүд: Гурван хялбар хэсэг. 3-р хэсэг: Процессын API (орчуулга)

Юуны өмнө бид main() функцийг оруулаад мөрийг дэлгэцэн дээр хэвлэнэ. Уг мөрөнд эх хувилбарт гэж нэрлэгддэг процессын танигч байдаг PID эсвэл процессын танигч. Энэ танигчийг UNIX-д процессыг илэрхийлэхэд ашигладаг. Дараагийн тушаал нь fork() гэж дуудна. Энэ үед процессын бараг яг хуулбарыг бий болгодог. OS-ийн хувьд систем дээр нэг програмын 2 хуулбар ажиллаж байгаа юм шиг харагдаж байгаа бөгөөд энэ нь эргээд fork() функцээс гарах болно. Шинээр үүсгэсэн хүүхэд процесс (үүнийг үүсгэсэн эх процесстой холбоотой) main() функцээс эхлэн цаашид ажиллахаа болино. Хүүхдийн процесс нь эцэг эхийн процессын яг хуулбар биш гэдгийг санах нь зүйтэй, ялангуяа энэ нь өөрийн хаягийн орон зай, өөрийн бүртгэлүүд, гүйцэтгэх зааварчилгааг зааж өгөх өөрийн заагч гэх мэт зүйлстэй байдаг. Тиймээс fork() функцийн дуудагч руу буцаасан утга өөр байх болно. Тодруулбал, эцэг эх процесс нь хүүхэд процессын PID утгыг буцаалт болгон хүлээн авах бөгөөд хүүхэд 0-тэй тэнцүү утгыг хүлээн авах болно. Эдгээр буцаах кодыг ашиглан та процессуудыг салгаж, тус бүрийг өөрийн ажлыг хийхийг албадах боломжтой. . Гэсэн хэдий ч, энэ хөтөлбөрийн хэрэгжилтийг нарийн тодорхойлоогүй байна. 2 процесст хуваасны дараа үйлдлийн систем нь тэдгээрийг хянаж, ажлаа төлөвлөж эхэлдэг. Хэрэв нэг цөмт процессор дээр хийгдсэн бол процессуудын аль нэг нь, энэ тохиолдолд эцэг эх нь үргэлжлүүлэн ажиллах бөгөөд дараа нь хүүхдийн процесс хяналтыг хүлээн авах болно. Дахин эхлүүлэх үед нөхцөл байдал өөр байж болно.

Дуудлага хүлээх()

Үйлдлийн системүүд: Гурван хялбар хэсэг. 3-р хэсэг: Процессын API (орчуулга)

Дараах програмыг анхаарч үзээрэй. Энэ хөтөлбөрт дуудлага байгаа тул хүлээх() Эцэг эхийн үйл явц нь хүүхдийн процесс дуусахыг үргэлж хүлээх болно. Энэ тохиолдолд бид дэлгэцэн дээр хатуу тодорхойлсон текст гаралтыг авах болно

Үйлдлийн системүүд: Гурван хялбар хэсэг. 3-р хэсэг: Процессын API (орчуулга)

exec() дуудна

Үйлдлийн системүүд: Гурван хялбар хэсэг. 3-р хэсэг: Процессын API (орчуулга)

Сорилтыг авч үзье exec(). Энэ системийн дуудлага нь бид огт өөр програм ажиллуулахыг хүссэн үед хэрэг болно. Энд бид залгах болно execvp() үг тоолох програм болох wc програмыг ажиллуулах. exec()-г дуудах үед юу болох вэ? Энэ дуудлагыг гүйцэтгэх файлын нэр болон зарим параметрүүдийг аргумент болгон дамжуулдаг. Үүний дараа энэ гүйцэтгэгдэх файлын код болон статик өгөгдлийг ачаалж, код бүхий өөрийн сегментийг дарж бичнэ. Стек болон овоо гэх мэт санах ойн үлдсэн хэсгүүдийг дахин эхлүүлнэ. Үүний дараа үйлдлийн систем нь програмыг ажиллуулж, түүнд олон аргумент дамжуулдаг. Тиймээс бид шинэ процесс үүсгээгүй, зүгээр л одоо ажиллаж байгаа програмыг өөр ажиллаж байгаа програм болгон хувиргасан. Үр удамд exec() дуудлагыг гүйцэтгэсний дараа анхны программ огт ажиллаагүй мэт харагдана.

Энэхүү эхлүүлэх хүндрэл нь Unix shell-ийн хувьд хэвийн үзэгдэл бөгөөд дуудсаны дараа уг бүрхүүлд код гүйцэтгэх боломжийг олгодог. сэрээ (), гэхдээ дуудлага хийхээс өмнө exec(). Ийм кодын жишээ нь програмыг эхлүүлэхийн өмнө түүний хэрэгцээнд нийцүүлэн бүрхүүлийн орчныг тохируулах явдал юм.

Шелл - зүгээр л хэрэглэгчийн програм. Тэр танд урилгын мөрийг үзүүлж, ямар нэгэн зүйл бичихийг хүлээж байна. Ихэнх тохиолдолд, хэрэв та тэнд програмын нэрийг бичвэл бүрхүүл нь түүний байршлыг олж, fork() аргыг дуудаж, дараа нь зарим төрлийн exec()-г дуудаж шинэ процесс үүсгэж, програмыг дуусгахыг хүлээнэ. хүлээх() дуудна. Хүүхдийн процесс гарахад бүрхүүл нь wait() дуудлагаас буцаж ирээд мөрийг дахин хэвлээд дараагийн командыг оруулахыг хүлээнэ.

Fork() & exec() хуваах нь бүрхүүлд дараах зүйлсийг хийх боломжийг олгодог, жишээлбэл:
wc файл > шинэ_файл.

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

Unix хоолой нь pipe() дуудлагыг ашигладагтай ижил төстэй байдлаар хэрэгждэг. Энэ тохиолдолд процессын гаралтын урсгал нь цөмд байрлах хоолойн дараалалд холбогдож, өөр процессын оролтын урсгал холбогдоно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх