Operētājsistēmas: trīs vienkāršas daļas. 3. daļa: procesa API (tulkošana)

Ievads operētājsistēmās

Čau Habr! Es vēlos vērst jūsu uzmanību uz vienas, manuprāt, interesantas literatūras - OSTEP - rakstu sēriju-tulkojumiem. Šajā materiālā diezgan dziļi aplūkots unix līdzīgu operētājsistēmu darbs, proti, darbs ar procesiem, dažādiem plānotājiem, atmiņu un citiem līdzīgiem komponentiem, kas veido modernu OS. Visu materiālu oriģinālus varat apskatīt šeit šeit. Lūdzu, ņemiet vērā, ka tulkojums tika veikts neprofesionāli (diezgan brīvi), bet es ceru, ka es saglabāju vispārējo nozīmi.

Laboratorijas darbus par šo tēmu var atrast šeit:

Citas daļas:

Varat arī apskatīt manu kanālu vietnē telegramma =)

Signalizācija! Šai lekcijai ir laboratorija! Skaties github

Procesa API

Apskatīsim piemēru procesa izveidei UNIX sistēmā. Tas notiek, izmantojot divus sistēmas zvanus dakša () и izpildīt().

Call fork ()

Operētājsistēmas: trīs vienkāršas daļas. 3. daļa: procesa API (tulkošana)

Apsveriet programmu, kas izsauc fork() izsaukumu. Tās izpildes rezultāts būs šāds.

Operētājsistēmas: trīs vienkāršas daļas. 3. daļa: procesa API (tulkošana)

Pirmkārt, mēs ievadām galveno () funkciju un izdrukājam virkni uz ekrāna. Rindā ir procesa identifikators, kas oriģinālā tiek izsaukts PID vai procesa identifikators. Šis identifikators tiek izmantots UNIX, lai atsauktos uz procesu. Nākamā komanda izsauks fork (). Šajā brīdī tiek izveidota gandrīz precīza procesa kopija. Šķiet, ka operētājsistēmā sistēmā darbojas 2 vienas un tās pašas programmas kopijas, kas savukārt izies no fork() funkcijas. Jaunizveidotais pakārtotais process (saistībā ar vecākprocesu, kas to izveidoja) vairs netiks izpildīts, sākot no galvenās () funkcijas. Jāatceras, ka pakārtotais process nav precīza vecākprocesa kopija; jo īpaši tam ir sava adrešu telpa, savi reģistri, savs rādītājs uz izpildāmām instrukcijām un tamlīdzīgi. Tādējādi fork() funkcijas izsaucējam atgrieztā vērtība būs atšķirīga. Jo īpaši vecākais process saņems pakārtotā procesa PID vērtību kā atdevi, un bērns saņems vērtību, kas vienāda ar 0. Izmantojot šos atgriešanas kodus, jūs varat atdalīt procesus un piespiest katru no tiem veikt savu darbu. . Tomēr šīs programmas izpilde nav stingri noteikta. Pēc sadalīšanas 2 procesos OS sāk tos uzraudzīt, kā arī plānot savu darbu. Ja tas tiek izpildīts viena kodola procesorā, viens no procesiem, šajā gadījumā vecākais, turpinās darboties, un pēc tam pakārtotais process saņems kontroli. Restartējot, situācija var atšķirties.

Zvanu gaidiet ()

Operētājsistēmas: trīs vienkāršas daļas. 3. daļa: procesa API (tulkošana)

Apsveriet šādu programmu. Šajā programmā zvana klātbūtnes dēļ gaidi () Vecāku process vienmēr gaidīs, līdz tiks pabeigts bērna process. Šajā gadījumā mēs ekrānā iegūsim stingri noteiktu teksta izvadi

Operētājsistēmas: trīs vienkāršas daļas. 3. daļa: procesa API (tulkošana)

exec() izsaukums

Operētājsistēmas: trīs vienkāršas daļas. 3. daļa: procesa API (tulkošana)

Apsveriet izaicinājumu izpildīt(). Šis sistēmas izsaukums ir noderīgs, ja vēlamies palaist pavisam citu programmu. Šeit mēs piezvanīsim execvp() lai palaistu wc programmu, kas ir vārdu skaitīšanas programma. Kas notiek, kad tiek izsaukts exec()? Šim izsaukumam kā argumenti tiek nodots izpildāmā faila nosaukums un daži parametri. Pēc tam tiek ielādēts kods un statiskie dati no šī izpildāmā faila, un tā segments ar kodu tiek pārrakstīts. Atlikušās atmiņas apgabali, piemēram, kaudze un kaudze, tiek atkārtoti inicializēti. Pēc tam OS vienkārši izpilda programmu, nododot tai argumentu kopu. Tāpēc mēs neizveidojām jaunu procesu, mēs vienkārši pārveidojām pašlaik darbojošos programmu par citu darbojošos programmu. Pēc exec() izsaukuma izpildes pēcnācējā, šķiet, ka sākotnējā programma nemaz nedarbosies.

Šī startēšanas komplikācija ir pilnīgi normāla Unix apvalkam un ļauj šim apvalkam izpildīt kodu pēc izsaukšanas dakša (), bet pirms zvana izpildīt(). Šāda koda piemērs varētu būt čaulas vides pielāgošana palaižamās programmas vajadzībām pirms tās palaišanas.

Apvalks - tikai lietotāja programma. Viņa parāda jums ielūguma rindiņu un gaida, kad jūs tajā kaut ko ierakstīsit. Vairumā gadījumu, ja tur ierakstāt programmas nosaukumu, apvalks atradīs tās atrašanās vietu, izsauks metodi fork() un pēc tam izsauks noteikta veida exec(), lai izveidotu jaunu procesu un gaidītu, līdz tas tiks pabeigts, izmantojot gaidi() zvanu. Kad pakārtotais process iziet, apvalks atgriezīsies no gaidīšanas () izsaukuma, vēlreiz izdrukā uzvedni un gaidīs, līdz tiks ievadīta nākamā komanda.

Fork () & exec () sadalījums ļauj apvalkam veikt šādas darbības, piemēram:
wc fails > jauns_fails.

Šajā piemērā wc programmas izvade tiek novirzīta uz failu. Veids, kā apvalks to panāk, ir pavisam vienkāršs – pirms zvanīšanas izveidojot bērna procesu izpildīt(), apvalks aizver standarta izvadi un atver failu jauns_fails, tādējādi visa izvade no tālāk darbojošās programmas wc tiks novirzīts uz failu, nevis uz ekrānu.

Unix caurule tiek īstenoti līdzīgā veidā, ar atšķirību, ka tie izmanto pipe() izsaukumu. Šajā gadījumā procesa izvades plūsma tiks savienota ar kodolā izvietoto cauruļu rindu, kurai tiks pievienota cita procesa ievades plūsma.

Avots: www.habr.com

Iegādājieties uzticamu mitināšanu vietnēm ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa vietņu mitināšanu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster