namai - Naršyklės
Daugiafunkcinis programavimas Linux sistemoje. Daugiafunkcinis Linux programavimo fonas ir prioritetinių procesų valdymas

Linux- daugiafunkcinis ir kelių vartotojų Operacinė sistemašvietimui, verslui, individualiam programavimui. Linux priklauso UNIX tipo operacinių sistemų šeimai.

„Linux“ iš pradžių parašė Linusas Torvaldsas, o vėliau ją patobulino daugybė žmonių visame pasaulyje. Tai Unix operacinės sistemos, vienos iš pirmųjų galingų operacinių sistemų, sukurtų kompiuteriams, klonas, tačiau jis nėra nemokamas. Tačiau jo kūrime nedalyvavo nei Unix System Laboratories, nei Unix kūrėjai, nei Berklio universitetas, Berkeley Software Distribution (BSD) kūrėjai. Vienas is labiausiai Įdomūs faktai Iš Linux istorijos yra tai, kad ją kuriant vienu metu dalyvavo žmonės iš viso pasaulio – nuo ​​Australijos iki Suomijos – ir tai daro iki šiol.

„Linux“ iš pradžių buvo sukurta veikti su 386 procesoriumi. Vienas iš pirmųjų Linuso Torvaldso projektų buvo programa, kuri galėjo perjungti procesus, iš kurių vienas spausdintų AAAA, o kitas spausdintų BBBB. Vėliau ši programa išaugo į Linux. Teisingiau būtų sakyti, kad Linus sukūrė OS branduolį ir yra atsakingas už jo stabilumą.

Linux palaiko daugumą populiarių Unix programinė įranga, įskaitant grafikos sistema X langas - tai yra daugybė programų, tačiau verta pabrėžti, kad Linux yra VISIŠKAI NEMOKAMAI. Daugiausia reikia sumokėti už pakuotę ir kompaktinį diską, kuriame įrašytas Linux platinimas. Paskirstymas yra pati OS + programinės įrangos paketų rinkinys, skirtas Linux. Taip pat verta paminėti, kad visa tai ateina su šaltinio kodu, o bet kuri programa, parašyta Linux, gali būti modifikuojama pagal jūsų poreikius. Tai taip pat leidžia perkelti bet kurią programą į bet kurią platformą - "Intel PC", "Macintosh". Beje, visa tai, kas išdėstyta pirmiau, įvyko fondo „Free Software Foundation“ dėka nemokamas programas, kuri yra GNU projekto dalis. Ir būtent šiems tikslams buvo sukurtas GPL – General Public License, kurio pagrindu Linux yra nemokama, kaip ir visa jai skirta programinė įranga, o komercinis Linux ar jos dalių programinės įrangos naudojimas yra draudžiamas. konfigūravimo sistema unix linux

Be to, kas išdėstyta aukščiau, Linux yra labai galinga ir stabili OS. Naudotis juo internete apsimoka, o įsilaužti nėra taip paprasta.

Šiandien „Linux“ kūrimas vyksta dviem kryptimis. Pirmoji su lyginiais versijų numeriais (2.0, 2.2, 2.4) laikoma stabilesne, patikimesne Linux versija. Antrasis, kurio versijos sunumeruotos nelyginiais skaičiais (2.1, 2.3), yra drąsesnis ir sparčiau besivystantis, todėl (deja) ir bugiškesnis. Bet čia jau skonio reikalas.

Linux sistemoje nėra atskyrimo vairuoja C, D, o ryšio su įrenginiais procesas yra labai patogus. Visi įrenginiai turi savo sistemos failas, visi diskai prijungti prie vienos failų sistemos ir viskas atrodo monolitiškai, viena. Aiški katalogo struktūra leidžia akimirksniu rasti bet kokią informaciją. Bibliotekos failams - savo katalogą, paleistiems failams - savo, failams su nustatymais - savo, įrenginio failams - savo ir pan.

Branduolio moduliškumas leidžia prijungti bet kokias OS paslaugas neperkraunant kompiuterio. Be to, galite perdaryti patį OS branduolį, nes branduolio šaltinio kodai taip pat yra prieinami bet kuriame paskirstyme.

„Linux“ OS labai meistriškai, taip sakant, naudoja kelių užduočių idėją, t.y. bet kokie sistemos procesai vykdomi vienu metu (palyginkite su Windows: failų kopijavimas į diskelį ir bandymas klausytis muzikos šiuo metu ne visada suderinami).

Tačiau ne viskas taip paprasta. „Linux“ yra šiek tiek sudėtingesnė nei „Windows“, ir ne visi gali lengvai į ją pereiti naudodami „Windows“. Iš pirmo žvilgsnio netgi gali atrodyti, kad tai labai nepatogu ir sunkiai konfigūruojama. Bet tai netiesa. Visas „Linux“ akcentas yra tai, kad galite ją pritaikyti sau, sukonfigūruoti taip, kad jaustumėte didelį pasitenkinimą naudodamiesi šia OS. Daugybė nustatymų leidžia keisti išorinę (ir vidinę) OS išvaizdą, o ne viena „Linux“ sistema bus panaši į jūsų. „Linux“ galite pasirinkti naudoti grafinį apvalkalą, yra keletas biuro paketai, serverio programos, ugniasienės... Tiesiog visa krūva įvairios programos kiekvienam skoniui.

1998 m. „Linux“ buvo sparčiausiai auganti serverių operacinė sistema, o tais metais jos naudojimas išaugo 212%. Šiandien yra daugiau nei 20 000 000 Linux vartotojų. Linux sistemoje yra daug programų, skirtų abiem naudojimui namuose, ir visiškai veikiančioms UNIX darbo stotims ir interneto serveriams.

Linux nebėra tik operacinė sistema. „Linux“ vis labiau primena kultą. Prieiti prie tiesos kulto atveju darosi vis sunkiau. Pradėkime nuo faktų. Taigi Linux yra:

  • * nemokamas (tiksliau, laisvai platinamas) Unix klonas;
  • * operacinė sistema su tikru multitaskingu;
  • * OS, kurią kiekvienas „vartotojas“ gali modifikuoti, nes galite rasti beveik bet kurios jos dalies šaltinio kodus;
  • * kuris sukonfigūruotas tiksliai taip, kaip norite, o ne taip, kaip pageidauja gamintojas.

„Linux“ naujokus pirmiausia traukia tai, kad ji „kieta“ ir madinga. Sklando mitas, kad ši operacinė sistema tikrai netinka galutiniam vartotojui. Norint surinkti patikimą ir atsparų įsilaužimui serverį, tai yra daugiau nei geras sprendimas, bet ne už paprastas vartotojas kuris reikalauja komforto, patogumo ir visai nenori suprasti ir jausti sistemos, su kuria šiuo metu dirba. Tai nėra visiškai tiesa. Pritaikyta Linux sistema su grafine sąsaja yra tokia pat paprasta naudoti ir intuityvi kaip ir Microsoft operacinė sistema. Tiesiog Linux nustatymas reikalauja daug pastangų ir žinių.

Dėl šių savo kūrimo ir tobulinimo savybių „Linux“ įgijo labai specifinių „charakterio bruožų“. Viena vertus, tai yra tipiška UNIX sistema, skirta kelių vartotojų ir kelių užduočių vykdymui. Kita vertus, yra tipiška įsilaužėlių, studentų ir apskritai bet kokių žmonių, kurie mėgsta nuolat mokytis ir suprasti viską iki smulkmenų, sistema. „Linux“ sąrankos ir naudojimo lankstumas tikriausiai neturi lygių. Galite jį naudoti tokiu lygiu, kuriuo veikia „win95“, ty turėti grafinį darbalaukį su visomis jo funkcijomis „Windows“ sistemoje: piktogramomis, užduočių juosta, kontekstinis meniu tt Be to, galite įdiegti darbalaukį, kuris niekuo nesiskirs išvaizda ir funkcijas iš Windows. (Bendrai kalbant, parinktys langų tvarkyklės„Linux“ sistemoje tiesiog nėra pabaigos – nuo ​​super spartiškojo „icewm“ iki itin sudėtingo „Enlightment + Gnome“). Kita vertus, „Linux“ suteikia jums precedento neturinčią prieigą prie aparatinės įrangos bet kokiu prieinamumo lygiu. Tiesa, tam neužteks spustelėti dešiniuoju pelės klavišu, teks išmokti SI ir kompiuterio architektūros. Bet žmogus, kuris kažkada pajuto šį minčių kvapą, šį programuotojo įkvėpimą, kai laikai mašiną „už ausų“ ir gali su ja padaryti viską, ką ji sugeba – toks žmogus niekada nebesugrįš. minkštos langų letenos.

Jei, naudodamas komercinę operacinę sistemą, vartotojas yra priverstas laukti kitos versijos išleidimo, kad gautų sistemą be ankstesnės versijos gedimų ir klaidų, tada Linux moduliškumas leidžia atsisiųsti naują branduolį, kuris išleidžiamas bent kartą per du mėnesius arba dar dažniau (stabili versija) .

Atsakymai į klausimą "Kas yra Linux?" galite rasti daug. Daugelis žmonių mano, kad Linux yra tik branduolys. Tačiau vien branduolys vartotojui nenaudingas. Nors branduolys neabejotinai yra Linux OS pagrindas, vartotojas turi nuolat dirbti su taikomosiomis programomis. Šios programos yra ne mažiau svarbios nei branduolys. Todėl Linux yra branduolio ir pagrindinių taikomųjų programų rinkinys, kuris paprastai įdiegiamas kiekviename kompiuteryje su šia operacine sistema. Branduolio ir taikomųjų programų sujungimas į vieną visumą atsispindi ir sistemos pavadinime: GNU/Linux. GNU yra projektas, skirtas sukurti programų rinkinį, panašų į tą, kuris paprastai pridedamas prie Unix tipo sistemos.

Dažnas Linux šalininkų skundas yra tas, kad kalbėdami apie Linux privalumus jie išvardija Windows trūkumus. Tačiau tai dažnai neišvengiama, nes viskas išmokstama lyginant, o dauguma kompiuterių vartotojų dabar yra susipažinę tik su „Windows“. Taigi, ką jums suteikia „Linux“?

Originalus: Light-Weight Processes: Dissecting Linux Threads
Autoriai: Vishal Kanaujia, Chetan Giridhar
Paskelbimo data: 2011 m. rugpjūčio 1 d
Vertimas: A. Panin
Vertimo paskelbimo data: 2012 m. spalio 22 d

Šiame straipsnyje, skirtame „Linux“ kūrėjams ir informatikos studentams, aprašomi gijų pagrindai ir jų diegimas naudojant „Linux“ paprastus procesus, pateikiami šaltinio kodo pavyzdžiai, kad būtų lengviau suprasti.

Programų gijos yra pagrindinis daugiafunkcinės programinės įrangos aplinkos elementas. Programos giją galima apibūdinti kaip proceso vykdymo aplinką; todėl kiekvienas procesas turi bent vieną giją. Daugiagija apima kelias lygiagrečias (daugiaprocesorinėse sistemose) ir paprastai sinchronizuotas proceso vykdymo aplinkas.

Programos gijos turi savo identifikatorius (gijos ID) ir gali būti vykdomos nepriklausomai viena nuo kitos. Jie tarpusavyje dalijasi viena proceso adresų erdve ir naudoja šią savybę kaip privalumą, leidžiančią apsikeisti duomenimis nenaudoti IPC kanalų (tarpprocesinių ryšių sistemų – bendros atminties, vamzdžių ir kitų sistemų). Proceso gijos gali sąveikauti – pavyzdžiui, nepriklausomos gijos gali gauti/pakeisti globalaus kintamojo reikšmę. Šis ryšio modelis pašalina IPC iškvietimus branduolio lygiu. Kadangi gijos veikia vienoje adresų erdvėje, gijų konteksto jungikliai yra greiti ir nereikalauja daug išteklių.

Kiekvieną programos giją užduočių planuoklis gali apdoroti atskirai, todėl kelių gijų programos puikiai tinka lygiagrečiam vykdymui kelių procesorių sistemose. Be to, siūlų kūrimas ir sunaikinimas yra greitas. Skirtingai nuo fork() skambučio, gija nesukuria pirminio proceso adresų erdvės kopijos; vietoj to gijos dalijasi adreso erdve kartu su kitais ištekliais, įskaitant failų ir signalų tvarkykles.

Kelių gijų programa naudoja išteklius optimaliai ir kiek įmanoma efektyviau. Tokioje programoje programos gijos sprendžia įvairias užduotis, atsižvelgiant į optimalų sistemos naudojimą. Viena gija gali nuskaityti failą iš disko, kita – įrašyti duomenis į lizdą. Abi gijos veiks kartu, būdamos nepriklausomos viena nuo kitos. Šis modelis optimizuoja sistemos naudojimą ir taip pagerina našumą.

Keletas įdomių savybių

Labiausiai žinoma darbo su gijomis ypatybė yra jų sinchronizavimas, ypač kai yra bendras išteklius, pažymėtas kaip kritinis segmentas. Tai yra kodo segmentas, kuris pasiekia bendrinamą šaltinį ir bet kuriuo metu neturėtų būti pasiekiamas daugiau nei viena gija. Kadangi kiekviena gija gali būti vykdoma nepriklausomai, prieiga prie bendrinamo šaltinio nekontroliuojama, todėl reikia naudoti sinchronizavimo primityvus, įskaitant mutexes (abipusį išskyrimą), semaforus, skaitymo / rašymo užraktus ir kt.

Šie primityvai leidžia programuotojams kontroliuoti prieigą prie bendro išteklių. Be to, kas išdėstyta pirmiau, gijos, kaip ir procesai, gali patekti į blokavimo arba laukimo būsenas, jei sinchronizavimo modelis nėra tinkamai sukurtas. Derinimas ir kelių gijų programų analizė taip pat gali būti gana sudėtinga.

Kaip gijos įdiegiamos Linux?

„Linux“ leidžia kurti ir naudoti kelių gijų programas. Vartotojo lygiu gijų diegimas sistemoje „Linux“ vyksta pagal atvirą standartą POSIX (nešiojamosios operacinės sistemos sąsaja, skirta uniX). Unix sistemos), pažymėta kaip IEEE 1003. Vartotojo lygio biblioteka (glibc.so Ubuntu) suteikia gijų POSIX API įgyvendinimą.

Linux sistemoje programos gijos egzistuoja dviejose atskirose erdvėse – vartotojo erdvėje ir branduolio erdvėje. Vartotojo erdvėje gijos kuriamos naudojant su POSIX suderinamą pthread bibliotekos API. Šios vartotojo erdvės gijos yra neatsiejamai susijusios su branduolio erdvės gijomis. Linux sistemoje branduolio erdvės gijos traktuojamos kaip „lengvi procesai“. Lengvas procesas yra pagrindinės vykdymo aplinkos vienetas. Skirtingai nuo įvairių UNIX versijų, įskaitant tokias sistemas kaip HP-UX ir SunOS, Linux neturi atskiros gijų sistemos. Procesas arba gija Linux sistemoje yra traktuojama kaip „užduotis“ ir naudoja tas pačias vidines struktūras (struktūrų struct task_structs serija).

Daugeliui procesų gijų, sukurtų vartotojo erdvėje, branduolyje yra su jais susieta keletas lengvų procesų. Pavyzdys iliustruoja šį teiginį: #include #įtraukti #įtraukti Int main() ( pthread_t tid = pthread_self(); int sid = syscall(SYS_gettid); printf ("LWP id yra %dn", sid); printf ("POSIX gijos ID yra %dn", tid); return 0; )

Naudodami ps įrankį galite gauti informacijos apie procesus, taip pat lengvus procesus / šių procesų gijas: kanaujia@ubuntu:~/Desktop$ ps -fL UID PID PPID LWP C NLWP STIME TTY TIME CMD kanaujia 17281 5191 17281 01 Birželio 11 tšk./ 2 00:00:02 bash kanaujia 22838 17281 22838 0 1 08:47 pts/2 00:00:00 ps -fL kanaujia 17647 14111 17647 14111 17647/00 60:0pts s

Kas yra lengvi procesai?

Lengvas procesas yra procesas, kuris palaiko vartotojo erdvės giją. Kiekviena vartotojo erdvės gija yra neatsiejamai susijusi su lengvu procesu. Lengvo proceso kūrimo procedūra skiriasi nuo įprasto proceso kūrimo procedūros; Vartotojo procesas „P“ gali turėti keletą susijusių paprastų procesų su tuo pačiu grupės ID. Grupavimas leidžia branduoliui skaidyti išteklius (ištekliai apima adresų erdvę, puslapius Fizinė atmintis(VM), signalų tvarkyklės ir failų aprašai). Tai taip pat leidžia branduoliui išvengti konteksto perjungimo, kai susiduria su šiais procesais. Išsamus dalijimasis ištekliais yra priežastis, kodėl šie procesai vadinami lengvaisiais.

Kaip Linux sukuria lengvus procesus?

IN Linux kūrimas lengvi procesai įgyvendinami naudojant nestandartinį klono() sistemos iškvietimą. Jis panašus į fork(), bet turi daugiau funkcijų. Paprastai fork() skambutis įgyvendinamas naudojant klono() skambutį su papildomų parametrų, nurodant išteklius, kurie bus dalijami tarp procesų. Iškvietus clone() sukuriamas procesas, kai vaikas dalijasi vykdymo laiko elementais su pirminiu, įskaitant atmintį, failų tvarkykles ir signalų tvarkykles. Pthread biblioteka taip pat naudoja iškvietimą clone() gijų įgyvendinimui. Žr. šaltinio kodo failą ./nptl/sysdeps/pthread/createthread.c glibc šaltinio kodo katalogo 2.11.2 versijoje.

Sukurkite savo lengvą procesą

Parodykime skambučio clone() naudojimo pavyzdį. Žiūrėti į šaltinis iš demo.c failo žemiau:

#įtraukti #įtraukti #įtraukti #įtraukti #įtraukti #įtraukti #įtraukti //Steck dydis 64kB #define STACK 1024*64 // Antrinė gija vykdys šią funkciją int threadFunction(void* argument) ( printf("įvedama antrinė gija\n"); close((int*)argument); printf( "išeina iš antrinės gijos\n"); grąžina 0; ) int main() ( void* stekūnas; pid_t pid; int fd; fd = open("/dev/null", O_RDWR); if (fd< 0) { perror("/dev/null"); exit(1); } // Резервирование памяти для стека stack = malloc(STACK); if (stack == 0) { perror("malloc: could not allocate stack"); exit(1); } printf("Creating child thread\n"); // Вызов clone() для создания дочернего потока pid = clone(&threadFunction, (char*) stack + STACK, SIGCHLD | CLONE_FS | CLONE_FILES |\ CLONE_SIGHAND | CLONE_VM, (void*)fd); if (pid == -1) { perror("clone"); exit(2); } // Ожидание завершения дочернего потока pid = waitpid(pid, 0, 0); if (pid == -1) { perror("waitpid"); exit(3); } // Попытка записи в файл закончится неудачей, так как поток // закрыл файл if (write(fd, "c", 1) < 0) { printf("Parent:\t child closed our file descriptor\n"); } // Освободить память, используемую для стека free(stack); return 0; }

Demo.c programa leidžia kurti gijas iš esmės taip pat, kaip pthread biblioteka. Tačiau tiesiogiai naudoti iškvietimą Clone() nepatartina, nes jei naudojamas neteisingai, kuriama programa gali sugesti. Funkcijos Clone () sintaksė Linux sistemoje pateikta žemiau: #include int klonas (int (*fn) (void *), void *child_stack, int vėliavėlės, void *arg);

Pirmasis argumentas yra gijos funkcija; jis vadinamas, kai pradedama gija. Sėkmingai užbaigus klono() iškvietimą, funkcija fn pradedama vykdyti kartu su iškvietimo procesu.

Kitas argumentas yra antrinio proceso krūvos atminties vietos rodyklė. Žingsnis prieš iškviečiant fork() ir clone() reikalauja, kad programuotojas rezervuotų atmintį ir perduotų žymeklį, kurį naudotų kaip antrinio proceso krūvą, nes pirminiai ir antriniai procesai dalijasi atminties puslapiais – tai apima ir krūvą. Antrinis procesas gali iškviesti kitą funkciją nei pirminis procesas, todėl reikalingas atskiras dėklas. Savo programoje šią atminties dalį rezervuojame krūvoje naudodami funkciją malloc (). Krūvos dydis nustatytas į 64 KB. Kadangi x86 dėklas auga žemyn, reikia imituoti panašų elgesį naudojant skirtą atmintį nuo skyriaus pabaigos. Dėl šios priežasties funkcijai clone() perduodame šį adresą: (char*) stack + STACK

Kitas vėliavėlių argumentas yra ypač svarbus. Tai leidžia nurodyti, kurie ištekliai turėtų būti bendrinami su sukurtu procesu. Pasirinkome bitmaskę SIGCHLD | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM aprašyta žemiau:

  • SIGCHLD: Baigusi gija siunčia SIGCHLD signalą pirminiam procesui. Nustačius šią parinktį, pirminis procesas gali naudoti laukimo () funkciją ir laukti, kol visos gijos bus baigtos.
  • CLONE_FS: bendrinkite failų sistemos informaciją tarp pirminio proceso ir gijos. Informacija apima šaknį Failų sistema, darbo katalogas ir umask vertė.
  • CLONE_FILES: bendrinkite failo deskriptorių lentelę tarp pirminio proceso ir gijos. Lentelės pakeitimai atsispindi pirminiame procese ir visose gijose.
  • CLOSE_SIGHAND : bendrinkite signalų tvarkyklės lentelę tarp pirminio ir antrinio procesų. Vėlgi, jei pirminis procesas arba viena iš gijų pakeičia signalo tvarkyklę, pakeitimas atsispindės kitų procesų lentelėse.
  • CLONE_VM: pirminis procesas ir gijos veikia toje pačioje atminties vietoje. Visi vieno iš jų įrašyti atminties įrašai arba atvaizdai yra prieinami kitiems procesams.

Paskutinis parametras yra argumentas, perduotas funkcijai (threadFunction), mūsų atveju failo deskriptorius.

Žr. anksčiau paskelbtą darbo su lengvaisiais procesais demo.c pavyzdį.

Gija uždaro failą (/dev/null), atidarytą pirminio proceso. Kadangi pirminis procesas ir gija dalijasi failo deskriptorių lentele, failo uždarymo operacija taip pat turi įtakos pirminiam procesui, todėl vėlesni rašymo () iškvietimai sugenda. Pirminis procesas laukia, kol gija baigsis (kai jis gauna SIGCHLD signalą). Po to jis atlaisvina rezervuotą atmintį ir grąžina valdymą.

Sukompiliuokite ir paleiskite programą kaip įprasta; išvestis turėtų būti panaši į žemiau pateiktą: $gcc demo.c $./a.out Kuriama antrinė gija antrinė gija įvedama antrinė gija išeinama Tėvas: vaikas uždarė failo deskriptorių $

„Linux“ palaiko veiksmingą, paprastą ir keičiamo dydžio gijų infrastruktūrą. Tai paskatino programuotojus domėtis eksperimentuoti ir kurti sriegimo bibliotekas, kurios naudoja clone() kaip pagrindinę funkciją.

Tęsiame „Linux“ branduolio kelių gijų temą. Praeitą kartą kalbėjau apie pertraukimus, jų apdorojimą ir užduočių rinkinius, o kadangi iš pradžių buvo numatyta, kad tai bus vienas straipsnis, savo pasakojime apie darbo eilę kreipsiuosi į užduočių rinkinius, darant prielaidą, kad skaitytojas su jomis jau susipažinęs.
Kaip ir praėjusį kartą, savo istoriją pasistengsiu padaryti kuo išsamesnę ir išsamesnę.

Straipsniai iš serijos:

  1. Daugiafunkcinis darbas Linux branduolyje: darbo eilė

Darbo eilė

Darbo eilė- tai sudėtingesni ir sunkesni subjektai nei užduočių rinkiniai. Visų įgyvendinimo subtilybių čia net nebandysiu aprašyti, bet tikiuosi, kad svarbiausius dalykus paanalizuosiu daugiau ar mažiau detaliau.
Darbo eilės, kaip ir užduočių rinkiniai, tarnauja atidėtam pertraukimų apdorojimui (nors jas galima naudoti ir kitiems tikslams), tačiau, skirtingai nei užduočių, jos vykdomos branduolio proceso kontekste, todėl jos neturi būti atominės ir gali naudoti miego režimą. () funkcija, įvairūs sinchronizavimo įrankiai ir kt.

Pirmiausia supraskime, kaip apskritai organizuojamas darbo eilės apdorojimo procesas. Paveikslėlyje parodyta labai apytiksliai ir supaprastintai, kaip viskas iš tikrųjų vyksta, išsamiai aprašyta žemiau.

Šioje tamsiojoje materijoje dalyvauja keli subjektai.
Pirma, darbo daiktas(trumpiau tik darbas) yra struktūra, apibūdinanti funkciją (pavyzdžiui, pertraukimų tvarkyklę), kurią norime suplanuoti.Ją galima laikyti užduočių struktūros analogu. Sudarant tvarkaraštį užduočių rinkiniai buvo įtraukti į eiles, paslėptas nuo vartotojo, tačiau dabar turime naudoti specialią eilę - darbo eilė.
Užduočių rinkinius renka planavimo funkcija, o darbo eilę apdoroja specialios gijos, vadinamos darbuotojais.
Darbininkas's užtikrina asinchroninį darbų vykdymą iš darbo eilės. Nors darbą jie vadina rotacijos tvarka, tačiau apskritai apie griežtą, nuoseklų vykdymą nekalbama: juk čia vyksta pirmenybė, miegas, laukimas ir pan.

Apskritai darbuotojai yra branduolio gijos, tai yra, juos valdo pagrindinis Linux branduolio planuoklis. Tačiau darbuotojai iš dalies įsikiša planuojant papildomą lygiagretaus darbų vykdymo organizavimą. Tai bus išsamiau aptarta toliau.

Norėdami apibūdinti pagrindines darbo eilės mechanizmo galimybes, siūlau ištirti API.

Apie eilę ir jos kūrimą

alloc_workqueue(fmt, flags, max_active, args...)
Parametrai fmt ir args yra pavadinimo ir jo argumentų printf formatas. Parametras max_activate yra atsakingas už maksimalų darbų skaičių, kurį iš šios eilės galima atlikti lygiagrečiai viename procesoriuje.
Eilę galima sukurti su šiomis vėliavėlėmis:
  • WQ_HIGHPRI
  • WQ_UNBOUND
  • WQ_CPU_INTENSIVE
  • WQ_FREEZABLE
  • WQ_MEM_RECLAIM
Ypatingas dėmesys turėtų būti skiriamas vėliavai WQ_UNBOUND. Atsižvelgiant į šios vėliavėlės buvimą, eilės skirstomos į surištas ir nepririštas.
Susietose eilėse Pridėjus darbai yra susieti su esamu CPU, ty tokiose eilėse darbai vykdomi jį suplanuojančiame branduolyje. Šiuo atžvilgiu surištos eilės primena užduočių rinkinius.
Nepririštose eilėse darbus galima atlikti bet kuriame branduolyje.

Svarbi darbo eilės diegimo Linux branduolyje ypatybė yra papildomas lygiagretaus vykdymo organizavimas, kuris yra susietose eilėse. Žemiau parašyta išsamiau, bet dabar pasakysiu, kad tai atliekama taip, kad būtų naudojama kuo mažiau atminties ir kad procesorius nestovi be darbo. Visa tai įgyvendinama darant prielaidą, kad vienas darbas nenaudoja per daug procesoriaus ciklų.
Tai netaikoma nepritvirtintų eilių atveju. Iš esmės tokios eilės tiesiog suteikia darbuotojams konteksto ir pradeda jas kurti kuo anksčiau.
Taigi, nepririštos eilės turėtų būti naudojamos, jei tikimasi daug procesoriaus darbo krūvio, nes tokiu atveju planuotojas pasirūpins lygiagrečiu vykdymu keliuose branduoliuose.

Pagal analogiją su užduočių rinkiniais, darbams galima priskirti vykdymo prioritetą, normalų arba aukštą. Pirmenybė yra bendra visai eilei. Pagal numatytuosius nustatymus eilė turi įprastą prioritetą ir, jei nustatote vėliavėlę WQ_HIGHPRI, tada atitinkamai aukštas.

Vėliava WQ_CPU_INTENSIVE prasminga tik surištoms eilėms. Ši vėliava yra atsisakymas dalyvauti papildomoje lygiagrečiojo vykdymo organizacijoje. Ši žyma turėtų būti naudojama, kai tikimasi, kad darbas sunaudos daug procesoriaus laiko, tokiu atveju geriau perkelti atsakomybę planuotojui. Tai išsamiau aprašyta toliau.

Vėliavos WQ_FREEZABLE Ir WQ_MEM_RECLAIM yra specifiniai ir nepatenka į temos sritį, todėl plačiau apie juos nesigilinsime.

Kartais prasminga nekurti savo eilių, o naudoti įprastas. Pagrindiniai:

  • system_wq – susieta eilė greitam darbui
  • system_long_wq – surišta eilė darbams, kurie, kaip tikimasi, užtruks ilgai
  • system_unbound_wq – nesusieta eilė

Apie darbus ir jų planavimą

Dabar užsiimkime darbais. Pirmiausia pažvelkime į inicijavimo, deklaravimo ir paruošimo makrokomandas:
DECLARE(_DELAYED)_WORK(vardas, void (*funkcija)(struct work_struct *darbas)); /* kompiliavimo metu */ INIT(_DELAYED)_WORK(_work, _func); /* vykdymo metu */ PREPARE(_DELAYED)_WORK(_work, _func); /*, kad pakeistumėte vykdomą funkciją */
Darbai įtraukiami į eilę naudojant šias funkcijas:
bool queue_work(struct workqueue_struct *wq, struct work_struct *darbas); bool queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay); /* darbas bus įtrauktas į eilę tik pasibaigus vėlavimui */
Tai verta panagrinėti išsamiau. Nors eilę nurodome kaip parametrą, iš tikrųjų darbai dedami ne pačioje darbo eilėje, kaip gali atrodyti, o visai kitame esete – worker_pool struktūros eilių sąraše. Struktūra darbininkų baseinas, tiesą sakant, yra svarbiausias subjektas organizuojant darbo eilės mechanizmą, nors vartotojui jis lieka užkulisiuose. Būtent su jais dirba darbuotojai, ir būtent juose yra visa pagrindinė informacija.

Dabar pažiūrėkime, kokie baseinai yra sistemoje.
Pirmiausia – susietų eilių telkiniai (paveikslėlyje). Kiekvienam CPU statiškai paskirstomi du darbuotojų telkiniai: vienas aukšto prioriteto darbui, kitas – darbui su įprastu prioritetu. Tai yra, jei turėsime keturis branduolius, tada bus tik aštuoni prijungti baseinai, nepaisant to, kad darbo eilės gali būti tiek, kiek norima.
Kai sukuriame darbo eilę, joje yra paslauga, skirta kiekvienam procesoriui baseino_darbo eilė(pwq). Kiekviena tokia pool_workqueue yra susieta su darbuotojų telkiniu, kuris yra priskirtas tam pačiam CPU ir pagal prioritetą atitinka eilės tipą. Per juos darbo eilė sąveikauja su darbuotojų telkiniu.
Darbuotojai atlieka darbus iš darbuotojų grupės be atrankos, neskirdami, kuriai darbo eilei jie priklausė iš pradžių.

Nepririštoms eilėms darbuotojų telkiniai paskirstomi dinamiškai. Visos eilės gali būti suskirstytos į lygiavertiškumo klases pagal jų parametrus ir kiekvienai tokiai klasei sukuriamas savo darbuotojų telkinys. Jie pasiekiami naudojant specialią maišos lentelę, kurioje raktas yra parametrų rinkinys, o reikšmė atitinkamai yra darbuotojų telkinys.
Tiesą sakant, nesurištoms eilėms viskas yra šiek tiek sudėtingiau: jei surištoms eilėms pwq ir eilės buvo sukurtos kiekvienam CPU, čia jos sukuriamos kiekvienam NUMA mazgui, tačiau tai yra papildomas optimizavimas, kurio mes nenagrinėsime išsamiai.

Visokių smulkmenų

Taip pat pateiksiu keletą API funkcijų, kad užbaigčiau vaizdą, bet apie jas nekalbėsiu išsamiai:
/* Priverstinis užbaigimas */ bool flush_work(struct work_struct *darbas); bool flush_delayed_work(struct delayed_work *dwork); /* Atšaukti darbo vykdymą */ bool cancel_work_sync(struct work_struct *work); bool cancel_delayed_work(struct delayed_work *dwork); bool cancel_delayed_work_sync(struct delayed_work *dwork); /* Ištrinti eilę */ void delete_workqueue(struct workqueue_struct *wq);

Kaip darbuotojai atlieka savo darbą

Dabar, kai susipažinome su API, pabandykime išsamiau suprasti, kaip visa tai veikia ir yra valdoma.
Kiekviename baseine yra darbuotojų, kurie atlieka užduotis, rinkinys. Be to, darbuotojų skaičius dinamiškai keičiasi, prisitaikydamas prie esamos situacijos.
Kaip jau išsiaiškinome, darbuotojai yra gijos, atliekančios darbą branduolio kontekste. Darbuotojas juos iš eilės paima vieną po kito iš su juo susieto darbuotojų telkinio, o darbuotojai, kaip jau žinome, gali priklausyti skirtingoms šaltinio eilėms.

Darbuotojai sąlyginai gali būti trijų loginių būsenų: jie gali būti neaktyvūs, dirbantys arba vadovaujantys.
Darbininkas gali stovėti be darbo ir nieko nedaryti. Tai, pavyzdžiui, kai visi darbai jau atliekami. Kai darbuotojas patenka į šią būseną, jis užmiega ir atitinkamai nevykdys tol, kol nebus pažadintas;
Jei telkinio valdymo nereikia ir suplanuotų darbų sąrašas nėra tuščias, darbuotojas pradeda juos vykdyti. Tokius darbuotojus sutartinai vadinsime bėgimas.
Jei reikia, darbuotojas prisiima vaidmenį vadovas baseinas. Grupėje gali būti tik vienas vadovaujantis darbuotojas arba jo nėra. Jos užduotis – išlaikyti optimalų darbuotojų skaičių viename baseine. Kaip jis tai daro? Pirmiausia ištrinami darbuotojai, kurie ilgą laiką nedirbo. Antra, nauji darbuotojai sukuriami, jei iš karto įvykdomos trys sąlygos:

  • dar liko atlikti užduočių (darbai baseine)
  • nedirbančių darbuotojų
  • nėra dirbančių darbuotojų (tai yra aktyvių ir nemiegančių)
Tačiau paskutinė sąlyga turi savų niuansų. Jei baseino eilės nėra prijungtos, į veikiančius darbuotojus neatsižvelgiama; jiems ši sąlyga visada galioja. Tas pats pasakytina ir tuo atveju, kai darbuotojas atlieka užduotį iš susietos, bet su vėliavėle WQ_CPU_INTENSIVE, eilės. Be to, susietų eilių atveju, kadangi darbuotojai dirba su darbais iš bendro telkinio (kuris yra vienas iš dviejų kiekvienam branduoliui aukščiau esančiame paveikslėlyje), paaiškėja, kad kai kurie iš jų yra skaičiuojami kaip dirbantys, o kai kurie – ne. Taip pat išplaukia, kad atliekant darbus nuo WQ_CPU_INTENSIVE eilės gali prasidėti ne iš karto, bet jos pačios netrukdo atlikti kitų darbų. Dabar turėtų būti aišku, kodėl ši vėliavėlė taip vadinama ir kodėl ji naudojama, kai tikimės, kad darbai užtruks ilgai.

Dirbančių darbuotojų apskaita vykdoma tiesiogiai iš pagrindinio Linux branduolio planavimo priemonės. Šis valdymo mechanizmas užtikrina optimalų lygiagretumo lygį, neleidžiant darbo eilėje susidaryti per daug darbuotojų, tačiau taip pat neleisdamas be reikalo per ilgai laukti darbo.

Tie, kurie domisi, gali pažvelgti į darbuotojo funkciją branduolyje, ji vadinama worker_thread().

Visas aprašytas funkcijas ir struktūras išsamiau rasite failuose include/linux/workqueue.h, branduolys/workqueue.c Ir kernel/workqueue_internal.h. Taip pat yra dokumentai apie darbo eilę Dokumentacija/darbo eilė.txt.

Taip pat verta paminėti, kad darbo eilės mechanizmas branduolyje naudojamas ne tik atidėto pertraukimo apdorojimui (nors tai gana dažnas scenarijus).

Taigi, mes pažvelgėme į atidėto pertraukimo valdymo mechanizmus Linux branduolyje - užduočių rinkinį ir darbo eilę, kurios yra ypatinga daugiafunkcinio darbo forma. Apie pertraukimus, užduočių rinkinius ir darbo eiles galite perskaityti Jonathano Corbeto, Grego Kroah-Hartmano, Alessandro Rubini knygoje „Linux įrenginių tvarkyklės“, nors ten esanti informacija kartais būna pasenusi.

LABORATORINIS DARBAS Nr.3

Kelių užduočių PROGRAMAVIMASLINUX

1. Darbo tikslas: Susipažinkite su gcc kompiliatoriumi, programų derinimo metodais ir darbo su procesais funkcijomis.

2. Trumpa teorinė informacija.

Minimalus gcc kompiliatoriaus jungiklių rinkinys yra - Wall (rodomos visos klaidos ir įspėjimai) ir - o (išvesties failas):

gcc – siena – o print_pid print_pid. c

Komanda sukurs vykdomąjį failą print_pid.

C standartinė biblioteka (libc, įdiegta Linux sistemoje glibc) naudojasi Unix System V (toliau SysV) daugiafunkcinėmis galimybėmis. Libc pid_t tipas apibrėžiamas kaip sveikasis skaičius, kuriame gali būti pid. Funkcija, kuri praneša apie dabartinio proceso pid, turi prototipą pid_t getpid(void) ir yra apibrėžta kartu su pid_t programoje unistd. h ir sys/types. h).

Norėdami sukurti naują procesą, naudokite šakutės funkciją:

pid_t šakutė(tuščia)

Įterpę atsitiktinio ilgio delsą naudodami miego ir rando funkcijas, galėsite aiškiau pamatyti kelių užduočių atlikimo efektą:

dėl to programa „užmigs“ atsitiktinį sekundžių skaičių: nuo 0 iki 3.

Norėdami iškviesti funkciją kaip antrinį procesą, tiesiog iškvieskite ją po šakojimo:

// jei veikia antrinis procesas, iškvieskite funkciją

pid=procesas(arg);

// išeiti iš proceso

Dažnai reikia paleisti kitą programą kaip vaiko procesą. Norėdami tai padaryti, naudokite exec šeimos funkcijas:

// jei veikia antrinis procesas, iškvieskite programą


if (execl(./file","failas",arg, NULL)<0) {

printf("KLAIDA paleidžiant procesą\n");

else printf("procesas pradėtas (pid=%d)\n", pid);

// išeiti iš proceso

Dažnai tėvų procesas turi keistis informacija su savo vaikais arba bent jau sinchronizuotis su jais, kad galėtų atlikti operacijas tinkamu laiku. Vienas iš būdų sinchronizuoti procesus yra su laukimo ir laukimo funkcijomis:

#įtraukti

#įtraukti

pid_t wait(int *status) – sustabdo esamo proceso vykdymą, kol baigsis bet kuris antrinis procesas.

pid_t waitpid (pid_t pid, int *statusas, int parinktys) – sustabdo esamo proceso vykdymą, kol baigsis nurodytas procesas arba patikrins, ar nurodytas procesas baigtas.

Jei reikia išsiaiškinti antrinio proceso būseną, kai jis baigiasi, ir jo grąžinamą reikšmę, naudokite makrokomandą WEXITSTATUS, kaip parametrą perduodant jai antrinio proceso būseną.

status=waitpid(pid,&statusas, WNOHANG);

if (pid == statusas) (

printf("PID: %d, rezultatas = %d\n", pid, WEXITSTATUS(būsena)); )

Norint pakeisti sukurtų procesų prioritetus, naudojamas prioritetas ir funkcijos. Prioritetai nustatomi diapazone nuo -20 (didžiausias) iki 20 (mažiausias), normalioji reikšmė yra 0. Atminkite, kad tik supervartotojas gali padidinti prioritetą virš normalaus!

#įtraukti

#įtraukti

int process(int i) (

setpriority(PRIO_PROCESS, getpid(),i);

printf("Apdorokite %d gijos ID: %d dirba su prioritetu %d\n",i, getpid(),getpriority(PRIO_PROCESS, getpid()));

return(getpriority(PRIO_PROCESS, getpid()));

Norėdami sustabdyti procesą, naudokite nužudymo funkciją:

#įtraukti

#įtraukti

int kill(pid_t pid, int sig);

Jei pid > 0, tai nurodo proceso, kuriam siunčiamas signalas, PID. Jei pid = 0, tada signalas siunčiamas į visus grupės, kuriai priklauso dabartinis procesas, procesus.

sig – signalo tipas. Kai kurie „Linux“ signalų tipai:

SIGKILL Dėl šio signalo procesas nedelsiant nutraukiamas. Procesas negali ignoruoti šio signalo.

SIGTERM Šis signalas yra prašymas nutraukti procesą.

SIGCHLD Sistema siunčia šį signalą procesui, kai vienas iš antrinių procesų baigiasi. Pavyzdys:

if (pid[i] == būsena) (

printf("ThreadID: %d baigtas su būsena %d\n", pid[i], WEXITSTATUS(būsena));

else nužudyti(pid[i],SIGKILL);

3. Metodiniai nurodymai.

3.1. Norėdami susipažinti su gcc kompiliatoriaus parinktimis ir C kalbos funkcijų aprašymais, naudokite man ir info instrukcijas.

3.2. Programoms derinti patogu naudoti įmontuotą Midnight Commander (MC) failų tvarkyklės redaktorių, kuris spalvotai paryškina įvairias kalbos konstrukcijas ir viršutinėje eilutėje nurodo žymeklio padėtį faile (eilutė, stulpelis). ekrano.

3.3. „Midnight Commander“ failų tvarkyklė turi komandų buferį, kurį galima iškviesti sparčiuoju klavišu - H, kurią galima perkelti naudojant žymeklio rodykles (aukštyn ir žemyn). Norėdami į komandų eilutę įterpti komandą iš buferio, naudokite klavišą , norėdami redaguoti komandą iš buferio - klavišai<- и ->, Ir .


3.4. Atminkite, kad dabartinis katalogas nėra kelyje, todėl iš komandinė eilutė turite paleisti programą kaip "./print_pid". MC tiesiog užveskite pelės žymeklį virš failo ir spustelėkite .

3.5. Norėdami peržiūrėti programos vykdymo rezultatą, naudokite sparčiuosius klavišus - O. Jie taip pat veikia failų redagavimo režimu.

3.6. Norint užregistruoti programos vykdymo rezultatus, patartina naudoti išvesties peradresavimą iš konsolės į failą: ./test > result. txt

3.7. Norėdami pasiekti failus, sukurtus Linux serveris, naudokite ftp protokolą, kliento programa kuri yra prieinama „Windows 2000“ ir yra įmontuota failų tvarkyklė TOL. Kuriame sąskaita ir slaptažodis toks pat kaip jungiantis per ssh.

4.1. Susipažinkite su gcc kompiliatoriaus parinktimis ir programų derinimo metodais.

4.2. Užduočių variantams iš laboratorinio darbo Nr. 1 parašykite ir derinkite programą, kuri įgyvendina sugeneruotą procesą.

4.3. Užduočių variantams nuo laboratoriniai darbai Nr.1 parašyti ir derinti programą, kuri įgyvendina pirminį procesą, kuris iškviečia ir stebi antrinių procesų būklę – programas (laukia, kol jos užbaigs arba sunaikina, priklausomai nuo pasirinkimo).

4.4. Užduočių variantams iš laboratorinio darbo Nr.1 ​​parašykite ir derinkite programą, kuri įgyvendina pirminį procesą, kuris iškviečia ir stebi antrinių procesų - funkcijų būklę (laukia jų užbaigimo arba naikina, priklausomai nuo varianto).

5. Užduočių parinktys.Žr. užduočių variantus iš laboratorinio darbo Nr. 1

6. Pranešimo turinys.

6.1. Darbo tikslas.

6.2. Užduoties parinktis.

6.3. Programų sąrašai.

6.4. Programos vykdymo protokolai.

7. Kontroliniai klausimai.

7.1. C programų kompiliavimo ir vykdymo Linux sistemoje ypatybės.

7.2. Kas yra pid, kaip jį nustatyti operacinėje sistemoje ir programoje?

7.3. Šakės funkcija – paskirtis, taikymas, grąžinimo reikšmė.

7.4. Kaip paleisti funkciją sukurtame procese? Programa?

7.5. Tėvų ir vaikų procesų sinchronizavimo būdai.

7.6. Kaip sužinoti sukurto proceso būseną jam pasibaigus ir grąžinamą vertę?

7.7. Kaip valdyti proceso prioritetus?

7.8. Kaip nužudyti procesą operacinėje sistemoje ir programoje?

Savo apvalkale įveskite šią komandą:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Ekrane bus rodomas visų sistemoje veikiančių procesų sąrašas. Jei norite suskaičiuoti procesų skaičių, įveskite kažką panašaus į šį:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

$ ps -e --no-headers | nl | uodega -n 1

74 4650 tšk./0 00:00:00 uodega

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Pirmasis skaičius yra sistemoje veikiančių procesų skaičius. KDE vartotojai gali naudoti kpm programą, o Gnome vartotojai gali naudoti programą gnome-system-monitor, norėdami gauti informacijos apie procesus. Tam ir skirta „Linux“, kad vartotojas galėtų daryti tą patį Skirtingi keliai.

Kyla klausimas: „Kas yra procesas? „Linux“ procesai, kaip ir failai, yra aksiominės sąvokos. Kartais procesas tapatinamas su veikianti programa tačiau taip būna ne visada. Tarkime, kad procesas yra sistemos darbinis vienetas, kuris kažką daro. Daugiafunkcinis darbas yra kelių procesų galimybė vienu metu egzistuoti vienoje sistemoje.

Linux yra daugiafunkcinė operacinė sistema. Tai reiškia, kad procesai jame veikia vienu metu. Žinoma, tai yra sąlyginė formuluotė. „Linux“ branduolys nuolat perjungia procesus, tai yra, laikas nuo laiko suteikia kiekvienam procesoriui šiek tiek laiko. Perjungimas vyksta gana greitai, todėl mums atrodo, kad procesai vyksta vienu metu.

Kai kurie procesai gali generuoti kitus procesus, sudarydami medžio struktūrą. Gamybos procesai vadinami tėvų arba tėvų procesais, o vaikai – vaikais arba vaikų procesais. Šio „medžio“ viršuje yra pradinis procesas, kurį branduolys automatiškai sukuria sistemos įkrovos proceso metu.

Kiekvienas procesas sistemoje yra susietas su neneigiamų sveikųjų skaičių pora: proceso identifikatoriumi PID (proceso identifikatorius) ir pirminio proceso identifikatoriumi PPID (parent Process Identifier). Kiekvieno proceso PID yra unikalus (tam tikru momentu), o PPID yra lygus pirminio proceso ID. Jei į apvalkalą įvesite komandą ps -ef, bus rodomas procesų sąrašas su jų PID ir PPID reikšmėmis (atitinkamai antrasis ir trečiasis stulpeliai). Šios komandos pavyzdys:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

UID PID PPID C STIME TTY LAIKAS CMD

šaknis 1 0 0 17:08? 00:00:00 /sbin/init

šaknis 2 0 0 17:08? 00:00:00

šaknis 3 2 0 17:08? 00:00:00

šaknis 4 2 0 17:08? 00:00:00

šaknis 5 2 0 17:08? 00:00:00

šaknis 6 2 0 17:08? 00:00:00

šaknis 7 2 0 17:08? 00:00:00

šaknis 8 2 0 17:08? 00:00:00

šaknis 9 2 0 17:08? 00:00:00

šaknis 10 2 0 17:08? 00:00:00

šaknis 11 2 0 17:08? 00:00:00

šaknis 12 2 0 17:08? 00:00:00

šaknis 13 2 0 17:08? 00:00:00

šaknis 14 2 0 17:08? 00:00:00

šaknis 15 2 0 17:08? 00:00:00

šaknis 16 2 0 17:08? 00:00:00

šaknis 17 2 0 17:08? 00:00:00

šaknis 18 2 0 17:08? 00:00:00

šaknis 19 2 0 17:08? 00:00:00

df00 16389 16387 0 20:10 pts/1 00:00:00 /bin/bash

df00 17446 2538 0 20:26? 00:00:00

df00 18544 2932 0 20:41 pts/2 00:00:00 /bin/bash -l

df00 19010 18544 0 20:48 tšk./2 00:00:00 ps -ef

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Reikėtų pažymėti, kad inicijavimo procesas visada turi identifikatorių 1, o PPID - 0. Nors iš tikrųjų nėra proceso, kurio identifikatorius yra 0. Proceso medį taip pat galima vizualizuoti naudojant ps programos parinktį --forest:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

2? 00:00:00 kthreadd

3 ?00:00:00 \_ migracija/0

4 ?00:00:00 \_ ksoftirqd/0

5 ?00:00:00 \_ sarginis šuo/0

6 ?00:00:00 \_ migracija/1

7 ?00:00:00 \_ ksoftirqd/1

8 ?00:00:00 \_ sarginis šuo/1

9 ?00:00:00 \_ įvykiai/0

10 ?00:00:00 \_ renginiai/1

11 ?00:00:00 \_ cpuset

12 ?00:00:00 \_ khelper

13 ?00:00:00 \_ netns

14 ?00:00:00 \_ async/mgr

15 ?00:00:00 \_ kintegrityd/0

16 ?00:00:00 \_ kintegrityd/1

18544 tšk./2 00:00:00 \_ bash

16388 ?00:00:00 \_ gnome-pty-helpe

16389 tšk./1 00:00:00 \_ bash

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Jei iškviečiate ps programą be argumentų, bus rodomas dabartinei grupei priklausančių procesų sąrašas, tai yra, veikiančių dabartiniame terminale.

Naudojant getpid() ir getppid()

Procesas gali sužinoti savo PID ir pirminį PPID naudodamas getpid () ir getppid () sistemos iškvietimus.

Getpid() ir getppid() sistemos iškvietimai turi šiuos prototipus:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

pid_t getpid(tuščia);

pid_t getppid(tuščia);

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Norint naudoti getpid() ir getppid(), antraštės failai unistd.h ir sys/types.h (pid_t tipo) turi būti įtraukti į programą naudojant #include direktyvą. Iškvietimas getpid() grąžina dabartinį proceso ID (PID), o getppid() grąžina pirminį ID (PPID). pid_t yra sveikojo skaičiaus tipas, kurio matmenys priklauso nuo konkrečios sistemos. Šio tipo reikšmės gali būti naudojamos kaip įprasti int tipo sveikieji skaičiai.

Dabar pasvarstykime paprasta programa, kuriame rodomas PID ir PPID, o tada užstoja, kol vartotojas nepaspaus .

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

#įtraukti

#įtraukti

#įtraukti

pid_t pid, ppid;

pid = getpid();

ppid = getppid();

printf("PID: %d\n", pid);

printf("PPID: %d\n", ppid);

fprintf(stderr, "Paspauskite išeiti...");

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Dabar pažiūrėkime, kaip ši programa veikia. Norėdami tai padaryti, sukompiliuokite ir paleiskite:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

$ gcc -o getpid getpid.c

Paspauskite išeiti...

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

Dabar, nespaudžiant , atidarykite kitą terminalo langą ir patikrinkite, ar getpid() ir getppid() sistemos iškvietimai veikia tinkamai:

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

$ ps -ef | grep getpid

df00 19724 19702 0 20:58 tšk./3 00:00:00 ./pag.

df00 19856 18544 0 21:00 pts/2 00:00:00 grep --colour=auto main

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−



 


Skaityti:



Geriausių belaidžių ausinių įvertinimas

Geriausių belaidžių ausinių įvertinimas

Ar galima nebrangiai įsigyti universalių ausų? 3000 rublių – ar už tokius pinigus galima nusipirkti kokybiškų ausinių? Kaip paaiškėjo, taip. Ir kalba...

Pagrindinė mobiliojo įrenginio kamera dažniausiai yra užpakalinėje korpuso dalyje ir naudojama fotografuoti bei filmuoti

Pagrindinė mobiliojo įrenginio kamera dažniausiai yra užpakalinėje korpuso dalyje ir naudojama fotografuoti bei filmuoti

Atnaujinta planšetės versija su patobulintomis charakteristikomis ir dideliu autonomiškumu.Acer išmanieji telefonai retai lankomi...

Kaip persijungti į kitą operatorių išsaugant savo numerį

Kaip persijungti į kitą operatorių išsaugant savo numerį

Įstatymas dėl telefono numerio išsaugojimo, kai abonentas pereina prie kito mobiliojo ryšio operatoriaus, Rusijoje įsigaliojo gruodžio 1 d. Tačiau paaiškėjo, kad...

phableto apžvalga, brangi, bet labai kompetentinga

phableto apžvalga, brangi, bet labai kompetentinga

Apžvalga apie phablet, brangus, bet labai kompetentingas 2015-03-20 Esu vienintelis batsiuvys pasaulyje be batų, išmaniųjų telefonų apžvalgininkas be savo išmaniojo telefono....

tiekimo vaizdas RSS