Upravlenie obrabotkoj signalov
CHtoby zadat' zhelaemyj sposob obrabotki dlya kazhdogo iz signalov, vy mozhete ispol'zovat' funkcii yazyka Si signal() standarta ANSI ili sigaction() standarta POSIX.
Funkciya sigaction() predostavlyaet bol'shie vozmozhnosti po upravleniyu obrabotkoj signalov.
Vy mozhete izmenit' sposob obrabotki signala v lyuboj moment vremeni. Esli vy ukazhete, chto signal dannogo tipa dolzhen ignorirovat'sya, to vse zhdushchie signaly takogo tipa budut nemedlenno otbrosheny.
Nekotorye special'nye zamechaniya kasayutsya processov, kotorye lovyat signaly posredstvom obrabotchikov signalov.
Vyzov obrabotchika signala analogichen programmnomu preryvaniyu. On vypolnyaetsya asinhronno po otnosheniyu k ostal'noj chasti processa. Takim obrazom, sushchestvuet veroyatnost' togo, chto obrabotchik signala budet vyzvan vo vremya vypolneniya lyuboj iz imeyushchihsya v programme funkcij (vklyuchaya bibliotechnye funkcii).
Esli v vashej programme ne predusmotren vozvrat iz obrabotchika signala, to mogut byt' ispol'zovany funkcii siglongjmp() libo longjmp() yazyka Si, odnako, funkciya siglongjmp() predpochtitel'nee. Pri ispol'zovanii funkcii longjmp() signal ostaetsya blokirovannym.
Inogda mozhet vozniknut' neobhodimost' vremenno zapretit' poluchenie signala, ne izmenyaya metod ego obrabotki. QNX predostavlyaet nabor funkcij, kotorye pozvolyayut blokirovat' poluchenie signalov. Blokirovannyj signal ostaetsya ozhidayushchim; posle razblokirovaniya on budet dostavlen vashej programme.
Poka vasha programma vypolnyaet obrabotchik signala dlya opredelennogo tipa signala, QNX avtomaticheski blokiruet etot signal. |to oznachaet, chto net neobhodimosti zabotit'sya o vlozhennyh vyzovah obrabotchika signala. Kazhdyj vyzov obrabotchika signala - eto nedelimaya operaciya po otnosheniyu k dostavke sleduyushchih signalov etogo tipa. Esli vash process vypolnyaet normal'nyj vozvrat iz obrabotchika, signal avtomaticheski razblokiruetsya.
Realizaciya obrabotchikov signalov v nekotoryh UNIX sistemah otlichaetsya tem, chto pri poluchenii signalov oni ne blokiruyut ego, a ustanavlivayut dejstvie po umolchaniyu. V rezul'tate nekotorye UNIX prilozheniya vyzyvayut funkciyu signal() iznutri obrabotchika signalov, chtoby podgotovit' obrabotchik k sleduyushchemu vyzovu. Takoj sposob imeet dva nedostatka. Vo-pervyh, esli sleduyushchij signal postupaet, kogda vasha programma uzhe vypolnyaet obrabotchik signala, no eshche ne vyzvala funkciyu signal(), to programma mozhet byt' zavershena. Vo-vtoryh, esli signal postupaet srazu posle vyzova funkcii signal() v obrabotchike, to vozmozhen rekursivnyj vhod v obrabotchik signala. QNX podderzhivaet blokirovanie signalov i, takim obrazom, ne stradaet ni ot odnogo iz etih nedostatkov. Vam ne nuzhno vyzyvat' funkciyu signal() iznutri obrabotchika signalov. Esli vy pokidaete obrabotchik cherez dal'nij perehod (long jump), vam sleduet ispol'zovat' funkciyu siglongjmp(). |
Sushchestvuet vazhnoe vzaimodejstvie mezhdu signalami i soobshcheniyami. Esli vash process SEND-blokirovan ili RECEIVE-blokirovan v moment polucheniya signala, i vy predusmotreli obrabotchik signala, proishodyat sleduyushchie dejstviya:
Esli process byl SEND-blokirovan v moment polucheniya signala, to problemy ne voznikaet, potomu chto poluchatel' eshche ne poluchil soobshchenie. No esli process byl RECEIVE-blokirovan, to vy ne uznaete, bylo li obrabotano poslannoe im soobshchenie i, sledovatel'no, ne budete znat', sleduet li povtoryat' Send().
Process, igrayushchij rol' servera (t.e. poluchayushchij soobshcheniya), mozhet zaprosit', chtoby on poluchal izveshchenie vsyakij raz, kogda ego process-klient poluchaet signal, nahodyas' v sostoyanii REPLY-blokirovan. V etom sluchae klient stanovitsya SIGNAL-blokirovannym s ozhidayushchim signalom. Server poluchaet special'nye soobshcheniya, opisyvayushchie tip signala. Server mozhet zatem vybrat' odin iz sleduyushchih variantov:
ILI
Kogda server otvechaet processu, kotoryj byl SIGNAL-blokirovan, to signal vydaetsya neposredstvenno posle vozvrata iz funkcii Send(), vyzvannoj klientom (processom-otpravitelem).
Prilozhenie v QNX mozhet obshchat'sya s processom na drugom komp'yutere seti tochno tak zhe, kak esli by ono obshchalos' s drugim processom na tom zhe samom komp'yutere. Kstati govorya, s tochki zreniya prilozheniya net razlichiya mezhdu lokal'nym i udalennym resursom.
Takaya zamechatel'naya stepen' prozrachnosti stanovitsya vozmozhna blagodarya virtual'nym kanalam (ot anglijskogo virtual circuit, sokrashchenno VC). VC - eto puti, kotorye Menedzher seti predostavlyaet dlya peredachi soobshchenij, proksi i signalov po seti. VC sposobstvuyut effektivnomu ispol'zovaniyu QNX-seti v celom po neskol'kim prichinam:
Process-otpravitel' otvechaet za podgotovku VC mezhdu soboj i tem processom, s kotorym on hochet ustanovit' svyaz'. S etoj cel'yu process-otpravitel' obychno vyzyvaet funkciyu qnx_vc_attach(). Krome sozdaniya VC, eta funkciya takzhe sozdaet na kazhdom konce kanala virtual'nyj identifikator processa, sokrashchenno VID. Dlya kazhdogo iz processov, VID na protivopolozhnom konce virtual'nogo kanala yavlyaetsya identifikatorom udalennogo processa, s kotorym on ustanavlivaet svyaz'. Processy podderzhivayut svyaz' drug s drugom posredstvom etih VID.
Naprimer, na sleduyushchem risunke virtual'nyj kanal soedinyaet PID 1 i PID 2. Na uzle 20 - gde nahoditsya PID 1 - VID predstavlyaet PID 2. Na uzle 40 - gde nahoditsya PID 2 - VID predstavlyaet PID 1. I PID 1 i PID 2 mogut obrashchat'sya k VID na svoem uzle tak zhe, kak k lyubomu drugomu lokal'nomu processu, posylaya soobshcheniya, prinimaya soobshcheniya, postavlyaya signaly, ozhidaya i t.d. Tak, naprimer, PID 1 mozhet poslat' soobshchenie VID na svoem konce, i etot VID peredast soobshchenie po seti k VID, predstavlyayushchemu PID 1 na drugom konce. |tot VID zatem otpravit soobshchenie k PID 2.
Svyaz' po seti realizuetsya posredstvom virtual'nyh kanalov. Kogda PID 1 posylaet dannye VID 2, poslannyj zapros peredaetsya po virtual'nomu kanalu, v rezul'tate VID 1 napravlyaet dannye PID 2.
Kazhdyj VID podderzhivaet soedinenie, kotoroe imeet sleduyushchie atributy:
Vozmozhno, vam ne pridetsya chasto imet' delo neposredstvenno s VC. Tak, naprimer, kogda prilozhenie hochet poluchit' dostup k resursu vvoda/vyvoda na drugom uzle seti, to VC sozdaetsya bibliotechnoj funkciej open() ot imeni prilozheniya. Prilozhenie ne prinimaet neposredstvennogo uchastiya v sozdanii ili ispol'zovanii VC. Analogichnym obrazom, kogda prilozhenie opredelyaet mestonahozhdenie servera s pomoshch'yu funkcii qnx_name_locate(), to VC avtomaticheski sozdaetsya ot imeni prilozheniya. Dlya prilozheniya VC prosto yavlyaetsya PID servera.
Dlya bolee podrobnoj informacii o funkcii qnx_name_locate() smotrite opisanie "Simvolicheskie imena processov v glave "Menedzher processov".
Virtual'noe proksi pozvolyaet posylat' proksi s udalennogo uzla, podobno tomu, kak virtual'nyj kanal pozvolyaet processu obmenivat'sya soobshcheniyami s udalennym uzlom.
V otlichie ot virtual'nogo kanala, kotoryj svyazyvaet vmeste dva processa, virtual'nyj proksi mozhet byt' poslan lyubym processom na udalennom uzle.
Virtual'nye proksi sozdayutsya funkciej qnx_proxy_rem_attach(), kotoroj v kachestve argumentov peredayutsya uzel (nid_t) i proksi (pid_t).
Na udalennom uzle sozdaetsya virtual'nyj proksi, kotoryj ssylaetsya na lokal'nyj proksi.
Imejte v vidu, chto na vyzyvayushchem uzle virtual'nyj kanal sozdaetsya avtomaticheski posredstvom funkcii qnx_proxy_rem_attach().
Otklyuchenie virtual'nyh kanalov
Process mozhet utratit' vozmozhnost' svyazi po ustanovlennomu VC v rezul'tate razlichnyh prichin:
Lyubaya iz etih prichin mozhet pomeshat' peredache soobshchenij po VC. Neobhodimo vyyavlyat' takie situacii s tem, chtoby prilozheniya mogli predprinyat' korrektiruyushchie dejstviya, libo korrektno zavershit' svoe vypolnenie. Esli eto ne budet sdelano, to cennye resursy mogut ostavat'sya bez neobhodimosti postoyanno zanyatymi.
Menedzher processov na kazhdom uzle proveryaet celostnost' VC na svoem uzle. On delaet eto sleduyushchim obrazom:
Dlya ustanovki parametrov, svyazannyh s dannoj proverkoj celostnosti VC, ispol'zujte utilitu netpoll.
Drugoj rasprostranennoj formoj sinhronizacii processov yavlyayutsya semafory. Operacii "signalizacii" (sem_post()) i "ozhidaniya" (sem_wait()) pozvolyayut upravlyat' vypolneniem processov, perevodya ih v sostoyanie ozhidaniya libo vyvodya iz nego. Operaciya signalizacii uvelichivaet znachenie semafora na edinicu, a operaciya ozhidaniya umen'shaet ego na edinicu.
Pri polozhitel'nom znachenii semafora, pri vypolnenii operacii ozhidaniya, process ne blokiruetsya. V protivnom sluchae operaciya ozhidaniya blokiruet process do teh por, poka kakoj-libo drugoj process ne vypolnit operaciyu signalizacii. Dopuskaetsya vypolnenie operacii signalizacii odin ili bolee raz pered vypolneniem operacii ozhidaniya - eto pozvolit odnomu ili neskol'kim processam vypolnit' operaciyu ozhidaniya, ne blokiruyas'.
Vazhnoe otlichie mezhdu semaforami i drugimi primitivami sinhronizacii zaklyuchaetsya v tom, chto semafory "asinhronno bezopasny" i mogut ispol'zovat'sya obrabotchikami signalov. Esli trebuetsya, chtoby obrabotchik signala vyvodil process iz sostoyaniya ozhidaniya, to semafory yavlyayutsya pravil'nym vyborom.
Kogda prinimayutsya resheniya po dispetcherizacii
Planirovshchik Mikroyadra prinimaet reshenie po dispetcherizacii:
V QNX kazhdomu iz processov prisvaivaetsya prioritet. Planirovshchik vybiraet dlya vypolneniya sleduyushchij process, nahodyashchijsya v sostoyanii READY, v sootvetstvii s ego prioritetom. (Programma v sostoyanii READY - eto programma, kotoraya sposobna ispol'zovat' CP). Dlya vypolneniya vybiraetsya process s naivysshim prioritetom.
V ocheredi shest' processov (A-F), gotovyh k vypolneniyu i nahodyashchihsya v sostoyanii READY. Ostal'nye processy (G-Z) blokirovany. V dannyj moment vypolnyaetsya process A. Processy A, B i C imeyut naivysshij prioritet, poetomu budut razdelyat' central'nyj processor v sootvetstvii s algoritmom dispetcherizacii dlya vypolnyaemogo processa.
Prioritety, prisvaivaemye processam, nahodyatsya v diapazone ot 0 (naimen'shij) do 31 (naivysshij). Uroven' prioriteta po umolchaniyu dlya sozdavaemogo processa nasleduetsya ot ego roditelya; dlya prilozhenij, zapuskaemyh komandnym processorom, prioritet obychno raven 10.
Esli vy hotite: | Ispol'zujte funkciyu yazyka SI: |
---|---|
Opredelit' prioritet processa | getprio() |
Ustanovit' prioritet dlya processa | setprio() |
CHtoby udovletvorit' potrebnost' razlichnyh prilozhenij, QNX predlagaet tri metoda dispetcherizacii:
Kazhdyj process v sisteme mozhet vypolnyat'sya, ispol'zuya lyuboj iz etih metodov. Oni dejstvuyut primenitel'no k kazhdomu otdel'nomu processu, a ne primenitel'no ko vsem processam na uzle.
Pomnite, chto eti metody dispetcherizacii primenimy, tol'ko kogda dva ili bolee processa s odinakovym prioritetom nahodyatsya v sostoyanii READY (t.e. eti processy neposredstvenno konkuriruyut drug s drugom). Esli process s bolee vysokim prioritetom perehodit v sostoyanie READY, to on nemedlenno vytesnyaet vse processy s bolee nizkim prioritetom.
Na sleduyushchej diagramme tri processa s odinakovym prioritetom nahodyatsya v sostoyanii READY. Esli process A blokiruetsya, to vypolnyaetsya process B.
Process A blokiruetsya, process B vypolnyaetsya.
Metod dispetcherizacii processa nasleduetsya ot ego roditel'skogo processa, odnako, zatem etot metod mozhet byt' izmenen.
Esli vy hotite: | Ispol'zujte funkciyu yazyka Si: |
---|---|
Opredelit' metod dispetcherizacii dlya processa | getscheduler() |
Ustanovit' metod dispetcherizacii dlya processa | setscheduler() |
Pri FIFO dispetcherizacii process prodolzhaet vypolnenie poka ne nastupit moment, kogda on:
FIFO dispetcherizaciya. Process A vypolnyaetsya do teh por, poka ne blokiruetsya.
Dva processa, kotorye vypolnyayutsya s odnim i tem zhe prioritetom, mogut ispol'zovat' metod FIFO dlya organizacii vzaimoisklyuchayushchego dostupa k razdelyaemomu (t.e. sovmestno ispol'zuemomu) resursu. Ni odin iz nih ne budet vytesnen drugim vo vremya svoego vypolneniya. Tak, naprimer, esli oni sovmestno ispol'zuyut segment pamyati, to kazhdyj iz etih dvuh processov mozhet obnovlyat' dannye v etom segmente, ne pribegaya k ispol'zovaniyu kakogo-libo sposoba sinhronizacii (naprimer, semafora).
Pri karusel'noj dispetcherizacii process prodolzhaet vypolnenie, poka ne nastupit moment, kogda on:
Karusel'naya dispetcherizaciya. Process A vypolnyaetsya do teh por, poka on ne ispol'zoval svoj kvant vremeni; zatem vypolnyaetsya sleduyushchij process, nahodyashchijsya v sostoyanii READY (process B).
Kvant vremeni - eto interval vremeni, vydelyaemyj kazhdomu processu. Posle togo, kak process ispol'zoval svoj kvant vremeni, upravlenie peredaetsya sleduyushchemu processu, kotoryj nahoditsya v sostoyanii READY i imeet takoj zhe uroven' prioriteta. Kvant vremeni raven 50 millisekundam.
Za isklyucheniem kvantovaniya vremeni, karusel'naya dispetcherizaciya identichna FIFO-dispetcherizacii. |
Pri adaptivnoj dispetcherizacii process vedet sebya sleduyushchim obrazom:
Adaptivnaya dispetcherizaciya. Process A ispol'zoval svoj kvant vremeni; ego prioritet snizilsya na 1. Vypolnyaetsya sleduyushchij process v sostoyanii READY (process B).
Vy mozhete ispol'zovat' adaptivnuyu dispetcherizaciyu v teh sluchayah, kogda processy, proizvodyashchie intensivnye vychisleniya, vypolnyayutsya v fonovom rezhime odnovremenno s interaktivnoj rabotoj pol'zovatelej. Vy obnaruzhite, chto adaptivnaya dispetcherizaciya daet proizvodyashchim intensivnye vychisleniya processam dostatochnyj dostup k CP i v to zhe vremya sohranyaet bystryj interaktivnyj otklik dlya drugih processov.
Adaptivnaya dispetcherizaciya yavlyaetsya metodom dispetcherizacii, ispol'zuyushchimsya po umolchaniyu dlya programm, zapuskaemyh komandnym interpretatorom.
V QNX obmen dannymi mezhdu processami v bol'shinstve sluchaev organizovan s ispol'zovaniem modeli klient/server. Servery vypolnyayut nekotorye servisnye funkcii, a klienty, posylaya soobshchenie serveru, zaprashivayut eti uslugi. Kak pravilo, servery bolee nadezhny i zhiznesposobny, chem klienty.
Kolichestvo klientov obychno bol'she, chem serverov. Kak sledstvie etogo, prinyato zapuskat' server s prioritetom bolee vysokim, chem u lyubogo iz ego klientov. Mozhet ispol'zovat'sya lyuboj iz treh rassmotrennyh vyshe metodov dispetcherizacii, no, navernoe, samym rasprostranennym yavlyaetsya karusel'nyj.
Esli klient s nizkim urovnem prioriteta posylaet soobshchenie serveru, to ego zapros vypolnyaetsya pod bolee vysokim urovnem prioriteta, tem, kotoryj imeetsya u servera. |to kosvennym obrazom povyshaet prioritet klienta, t.k. imenno ego zapros zastavil server vypolnyat'sya.
Poka dlya vypolneniya zaprosa serveru dostatochno korotkogo promezhutka vremeni, problem obychno ne voznikaet. Esli zhe vypolnenie zaprosa zanimaet u servera bolee prodolzhitel'noe vremya, to klient s nizkim prioritetom mozhet neblagopriyatno povliyat' na vypolnenie drugih processov, prioritety kotoryh vyshe, chem u klienta, no nizhe, chem u servera.
CHtoby reshit' etu dilemmu, server mozhet postavit' svoj prioritet v zavisimost' ot prioriteta togo klienta, chej zapros on vypolnyaet. Kogda server poluchaet soobshchenie, prioritet budet ustanovlen takim zhe, kak u klienta. Obratite vnimanie, chto izmenilsya tol'ko prioritet servera - ego algoritm dispetcherizacii ostaetsya neizmennym. Esli vo vremya vypolneniya zaprosa server poluchaet drugoe soobshchenie, i prioritet novogo klienta vyshe, chem u servera, to prioritet servera povyshaetsya. Fakticheski, novyj klient "zaryazhaet" server do svoego urovnya prioriteta, pozvolyaya emu zakonchit' vypolnenie tekushchego zaprosa i pristupit' k obrabotke zaprosa novogo klienta. Esli etogo ne delat', to fakticheski prioritet novogo klienta ponizitsya, poka on blokirovan na servere s nizkim prioritetom.
Esli vy vybrali klient-upravlyaemyj prioritet dlya svoego servera, vam sleduet takzhe zaprosit' dostavku soobshchenij v poryadke ubyvaniya prioritetov (v protivopolozhnost' hronologicheskomu).
CHtoby ustanovit' klient-upravlyaemyj prioritet, ispol'zujte funkciyu Si qnx_pflags() sleduyushchim obrazom:
qnx_pflags(~0, _PPF_PRIORITY_FLOAT | _PPF_PRIORITY_REC, 0, 0);
Kak by my etogo ne hoteli, komp'yutery ne yavlyayutsya beskonechno bystrymi. Dlya sistemy real'nogo vremeni zhiznenno vazhno, chtoby takty raboty CP ne rashodovalis' zrya. Takzhe ochen' vazhno svesti k minimumu vremya, kotoroe prohodit s momenta nastupleniya vneshnego sobytiya do nachala vypolneniya koda programmy, otvetstvennoj za obrabotku dannogo sobytiya. |to vremya nazyvaetsya zaderzhkoj.
V QNX sisteme vstrechaetsya neskol'ko vidov zaderzhek.
Zaderzhka preryvaniya - eto interval vremeni mezhdu apparatnym preryvaniem i vypolneniem pervoj komandy programmnogo obrabotchika preryvaniya. QNX prakticheski vse vremya ostavlyaet preryvaniya polnost'yu razreshennymi, poetomu zaderzhka preryvaniya, kak pravilo, ne sushchestvenna. Odnako nekotorye kriticheskie fragmenty koda trebuyut, chtoby preryvaniya byli vremenno zapreshcheny. Maksimal'naya prodolzhitel'nost' takogo zapreta obychno opredelyaet hudshij sluchaj zaderzhki preryvaniya - v QNX eto ochen' nebol'shaya velichina.
Sleduyushchaya diagramma illyustriruet sluchaj, kogda apparatnoe preryvanie obrabatyvaetsya v ustanovlennom obrabotchikom preryvanii. Obrabotchik preryvaniya libo prosto vypolnit komandu vozvrata, libo pri vozvrate zapustit proksi.
Obrabotchik preryvaniya prosto zavershaetsya.
Zaderzhka preryvaniya (Til) na privedennoj vyshe diagramme otrazhaet minimal'nuyu zaderzhku - sluchaj, kogda preryvaniya byli polnost'yu razresheny v moment, kogda proizoshlo preryvanie. V hudshem sluchae zaderzhka preryvaniya sostavit eto vremya plyus naibol'shee vremya, v techenie kotorogo QNX ili vypolnyayushchijsya process zapreshchaet preryvaniya CP.
Sleduyushchaya tablica soderzhit tipichnye znacheniya zaderzhki preryvaniya (Tqqq1ilqqq0) dlya raznyh processorov:
Zaderzhka preryvaniya (Til): | Processor: |
---|---|
3.3 mikrosekundy | 166 MGc Pentium |
4.4 mikrosekundy | 100 MGc Pentium |
5.6 mikrosekundy | 100 MGc 486DX4 |
22.5 mikrosekundy | 33 MGc 386EX |
V nekotoryh sluchayah obrabotchik apparatnogo preryvaniya nizkogo urovnya dolzhen peredat' upravlenie processu bolee vysokogo urovnya. V etom sluchae obrabotchik preryvaniya pered vypolneniem komandy "vozvrat" zapuskaet proksi. Zdes' imeet mesto vtoroj vid zaderzhki - zaderzhka dispetcherizacii, - s kotoroj takzhe nado schitat'sya.
Zaderzhka dispetcherizacii - eto vremya mezhdu zaversheniem raboty obrabotchika preryvaniya i vypolneniem pervoj komandy processa-drajvera. |to vremya, neobhodimoe dlya sohraneniya konteksta, vypolnyayushchegosya v dannyj moment vremeni processa, i vosstanovleniya konteksta trebuemogo drajvera. V QNX eto vremya takzhe neveliko, hotya i bol'she zaderzhki preryvaniya.
Obrabotchik preryvaniya zavershaet rabotu i zapuskaet proksi.
Vazhno otmetit', chto obrabotka bol'shinstva preryvanij zavershaetsya bez zapuska proksi. V bol'shinstve sluchaev obrabotchik preryvaniya sam mozhet vypolnit' vse neobhodimye dejstviya. Zapusk proksi, chtoby "razbudit'" drajver, process bolee vysokogo urovnya, proishodit tol'ko pri nastuplenii vazhnogo sobytiya. Naprimer, obrabotchik preryvaniya dlya drajvera posledovatel'nogo porta pri kazhdom preryvanii "registr peredachi svoboden" budet peredavat' odin bajt dannyh i zapustit process bolee vysokogo urovnya (Dev) tol'ko togda, kogda vyhodnoj bufer, nakonec, opusteet.
Sleduyushchaya tablica soderzhit tipichnye znacheniya zaderzhki dispetcherizacii (Tsl) dlya raznyh processorov:
Zaderzhka dispetcherizacii (Tsl): | Processor: |
---|---|
4.7 mikrosekundy | 166 MGc Pentium |
6.7 mikrosekundy | 100 MGc Pentium |
11.1 mikrosekundy | 100 MGc 486DX4 |
74.2 mikrosekundy | 33 MGc 386EX |
Tak kak arhitektura mikrokomp'yuterov pozvolyaet naznachat' prioritety apparatnym preryvaniyam, to preryvaniya s bolee vysokim prioritetom mogut vytesnyat' preryvaniya s men'shim prioritetom.
|tot mehanizm polnost'yu podderzhivaetsya v QNX. Vyshe byli rassmotreny prostejshie - i naibolee tipichnye - situacii, kogda proishodit tol'ko odno preryvanie. Prakticheski takoj zhe raschet vremeni spravedliv dlya preryvaniya s naivysshim prioritetom. Pri rassmotrenii naihudshego sluchaya dlya preryvaniya s nizkim prioritetom neobhodimo uchityvat' vremya obrabotki vseh preryvanij bolee vysokogo urovnya, t.k. v QNX preryvanie s bolee vysokim prioritetom vytesnit preryvanie s men'shim prioritetom.
Vypolnyaetsya process A. Preryvanie IRQx vyzyvaet vypolnenie obrabotchika preryvaniya Intx, kotoryj vytesnyaetsya IRQy i ego obrabotchikom Inty. Inty zapuskaet proksi, vyzyvayushchee vypolnenie processa B, a Intx zapuskaet proksi, vyzyvayushchee vypolnenie processa C.
|ta glava ohvatyvaet sleduyushchie temy:
Obyazannosti Menedzhera processov
Menedzher processov tesno vzaimodejstvuet s Mikroyadrom, chtoby obespechit' uslugi, sostavlyayushchie sushchnost' operacionnoj sistemy. Hotya on i yavlyaetsya edinstvennym processom, kotoryj ispol'zuet to zhe adresnoe prostranstvo, chto i Mikroyadro, Menedzher processov vypolnyaetsya kak istinnyj process. I on, kak i vse ostal'nye processy, podvergaetsya dispetcherizacii so storony YAdra i ispol'zuet predostavlyaemye Mikroyadrom primitivy peredachi soobshchenij dlya svyazi s drugimi processami v sisteme.
Menedzher processov otvechaet za sozdanie novyh processov v sisteme i za upravlenie osnovnymi resursami, svyazannymi s processom. Vse eti uslugi predostavlyayutsya posredstvom soobshchenij. Tak, naprimer, esli process hochet porodit' novyj process, on delaet eto, posylaya soobshchenie s ukazaniem atributov sozdavaemogo processa. Obratite vnimanie, chto t.k. soobshcheniya peredayutsya po seti, vy mozhete legko sozdat' process na drugom uzle seti, poslav soobshchenie Menedzheru processov na etom uzle.
QNX podderzhivayut tri primitiva sozdaniya processa:
Primitivy fork() i exec() opredeleny standartom POSIX, a primitiv spawn() realizovan tol'ko v QNX.
Primitiv fork() sozdaet novyj process, kotoryj yavlyaetsya tochnoj kopiej vyzvavshego ego processa. Novyj process ispol'zuet tot zhe samyj kod, chto i porodivshij ego process, i nasleduet kopiyu vseh dannyh roditel'skogo processa.
Primitiv exec() zamenyaet vyzvavshij process novym. Posle uspeshnogo vyzova exec() vozvrata ne proishodit, t.k. obraz vyzyvayushchego processa zamenyaetsya obrazom novogo processa. Obychnoj praktikoj v POSIX-sistemah dlya sozdaniya novogo processa - bez udaleniya vyzyvayushchego processa - yavlyaetsya snachala vyzov fork(), a zatem vyzov exec() iz porozhdennogo processa.
Primitiv spawn() sozdaet novyj process kak potomok vyzyvayushchego processa. S ego pomoshch'yu mozhno izbezhat' vyzovov fork() i exec(), ispol'zuya bolee bystryj i effektivnyj sposob sozdaniya novyh processov. V otlichie ot fork() i exec(), kotorye po svoej prirode vypolnyayutsya na tom zhe samom uzle, chto i vyzyvayushchij process, primitiv spawn() mozhet sozdavat' processy na lyubom uzle seti.
Kogda s pomoshch'yu odnogo iz treh rassmotrennyh vyshe primitivov zadaetsya novyj process, on nasleduet mnogoe iz svoego okruzheniya ot roditelya. |to svedeno v sleduyushchuyu tablicu:
Nasleduemyj parametr | fork() | exec() | spawn() |
---|---|---|---|
Identifikator processa | net | da | net |
Otkrytye fajly | da | po vyboru* | po vyboru |
Blokirovka fajlov | net | da | net |
Ozhidayushchie signaly | net | da | net |
Maska signalov | da | po vyboru | po vyboru |
Ignoriruemye signaly | da | po vyboru | po vyboru |
Obrabotchiki signalov | da | net | net |
Peremennye okruzheniya | da | po vyboru | po vyboru |
Identifikator seansa | da | da | po vyboru |
Gruppa processa | da | da | po vyboru |
Real'nye UID, GID | da | da | da |
|ffektivnye UID, GID | da | po vyboru | po vyboru |
Tekushchij rabochij katalog | da | po vyboru | po vyboru |
Maska sozdaniya fajlov | da | da | da |
Prioritet | da | po vyboru | po vyboru |
Algoritm dispetcherizacii | da | po vyboru | po vyboru |
Virtual'nye kanaly | net | net | net |
Simvol'nye imena | net | net | net |
tajmery real'nogo vremeni | net | net | net |
*po vyboru: vyzyvayushchij process mozhet po neobhodimosti vybrat' - da ili net.
Process prohodit cherez chetyre stadii:
Sozdanie novogo processa sostoit iz prisvoeniya novomu processu identifikatora (ID) processa i podgotovki informacii, kotoraya opredelyaet okruzhenie novogo processa. Bol'shaya chast' etoj informacii nasleduetsya ot roditel'skogo processa (smotri razdel "Nasledovanie").
Zagruzka obraza processa proizvoditsya nit'yu zagruzchika. Kod zagruzchika nahoditsya v Menedzhere processov, no nit' vypolnyaetsya pod ID novogo processa. |to pozvolyaet Menedzheru processov obrabatyvat' i drugie zaprosy vo vremya zagruzki programmy.
Posle togo, kak kod programmy zagruzhen, process gotov k vypolneniyu; on nachinaet konkurirovat' s ostal'nymi processami za resursy CP. Zamet'te, chto vse processy vypolnyayutsya parallel'no so svoimi roditelyami. Krome togo, smert' roditel'skogo processa ne oznachaet avtomaticheskuyu smert' ego dochernih processov.
Process zavershaetsya odnim iz dvuh sposobov:
Zavershenie vklyuchaet dve stadii:
Esli roditel'skij process ne vyzval wait() ili waitpid(), to dochernij process stanovitsya "zombi" i ne budet zavershen, poka roditel'skij process ne vyzovet wait() ili ne zavershit vypolnenie. (Esli vy ne hotite, chtoby process zhdal smerti dochernih processov, vy dolzhny libo ustanovit' _SPAWN_NOZOMBIE flag funkciyami qnx_spawn() ili qnx_spawn_options(), libo ustanovit' dejstvie SIG_IGN dlya signala SIGCHLD posredstvom funkcii signal(). Takim obrazom, dochernie processy ne budut stanovit'sya zombi posle smerti.)
Roditel'skij process mozhet zhdat' smerti dochernego processa, zapushchennogo na udalennom uzle. Esli roditel' processa-zombi umiraet, to zombi osvobozhdaetsya.
Esli zapushchena utilita dumper i process zavershaetsya v rezul'tate polucheniya signala, to generiruetsya damp pamyati. Vy mozhete zatem issledovat' ego s pomoshch'yu otladchika.
Process vsegda nahoditsya v odnom iz sleduyushchih sostoyanij:
Dlya polucheniya bolee polnoj informacii o blokirovannom sostoyanii obratites' k glave "Mikroyadro". |
Vozmozhnye sostoyaniya processa v QNX.
Pokazany sleduyushchie perehody:
Opredelenie sostoyanij processa
CHtoby opredelit' sostoyanie konkretnogo processa iz komandnogo interpretatora (Shell), ispol'zujte utility ps i sin (vnutri prilozhenij ispol'zujte funkciyu qnx_psinfo()).
CHtoby opredelit' sostoyanie operacionnoj sistemy v celom iz komandnogo interpretatora (Shell), ispol'zujte utilitu sin (vnutri prilozhenij ispol'zujte funkciyu qnx_osinfo()).
Utilita ps opredelena standartom POSIX; ee ispol'zovanie v komandnyh fajlah mozhet byt' perenosimym v drugie sistemy. Utilita sin, naprotiv, unikal'na dlya QNX; ona daet vam poleznuyu informaciyu, specificheskuyu dlya QNX, kotoruyu vy ne mozhete poluchit', ispol'zuya utilitu ps.
QNX stimuliruet razrabotku prilozhenij, kotorye razbity na neskol'ko vzaimodejstvuyushchih processov. Takoe prilozhenie, kotoroe sushchestvuet kak gruppa vzaimodejstvuyushchih processov, imeet bol'shie vozmozhnosti rasparallelivaniya i mozhet byt' raspredeleno po seti dlya luchshej proizvoditel'nosti.
Odnako razdelenie prilozhenij na vzaimodejstvuyushchie processy trebuet ryada special'nyh soobrazhenij. CHtoby vzaimodejstvuyushchie processy mogli ustanovit' svyaz' mezhdu soboj, oni dolzhny imet' vozmozhnost' opredelit' identifikatory drug druga. Naprimer, dopustim, chto imeetsya server bazy dannyh, kotoryj mozhet obsluzhivat' proizvol'noe kolichestvo klientov. Klienty mogut zapuskat'sya i prekrashchat' rabotu v lyuboe vremya, odnako server vsegda ostaetsya dostupnym. Kak processy-klienty uznayut identifikator processa-servera bazy dannyh s tem, chtoby poslat' emu soobshchenie?
V QNX processy mogut prisvaivat' sebe simvol'nye imena. V kontekste odnogo uzla processa mogut zaregistrirovat' eti imena u Menedzhera processov na tom uzle, na kotorom oni vypolnyayutsya. Ostal'nye processy mogut zatem zaprosit' u Menedzhera processov identifikator processa, associirovannyj s opredelennym imenem.
Situaciya stanovitsya bolee slozhnoj, esli my rassmotrim set', v kotoroj server obsluzhivaet klientov, nahodyashchihsya na razlichnyh uzlah. Poetomu v QNX predusmotrena podderzhka kak global'nyh, tak i lokal'nyh imen. Global'nye imena opredeleny dlya vsej seti, v to vremya kak lokal'nye imena opredeleny tol'ko dlya togo uzla, na kotorom oni zaregistrirovany. Global'nye imena na