А.В. Столяров - Введение в операционные системы (1114673), страница 21
Текст из файла (страница 21)
 ñëó÷àå, åñëè äî÷åðíèå ïðîöåññû åñòü, íî íè îäèí èç íèõåùå íå çàâåðøèëñÿ (òî åñòü íåò íè îäíîãî çîìáè, êîòîðîãî ìîæíî ñíÿòü),âûçîâ æäåò çàâåðøåíèÿ ëþáîãî èç äî÷åðíèõ ïðîöåññîâ (îòñþäà íàçâàíèå âûçîâà − wait, àíãë. æäàòü ). ñëó÷àå óñïåõà âûçîâ âîçâðàùàåò pid çàâåðøèâøåãîñÿ ïðîöåññà. Åñëèïàðàìåòð ïðåäñòàâëÿë ñîáîé íåíóëåâîé óêàçàòåëü, â öåëî÷èñëåííóþ ïåðåìåííóþ, íà êîòîðóþ îí óêàçûâàë, çàïèñûâàåòñÿ èíôîðìàöèÿ î êîäå çàâåðøåíèÿ ïðîöåññà èëè î íîìåðå ñèãíàëà, ïî êîòîðîìó ïðîöåññ áûë ñíÿò.
Äëÿàíàëèçà èíôîðìàöèè â ýòîé ïåðåìåííîé èñïîëüçóþòñÿ ìàêðîñû WIFEXITED,WIFSIGNALED (áûë ëè ïðîöåññ çàâåðøåí îáû÷íûì ñïîñîáîì èëè ïî ñèãíàëó),WEXITSTATUS (åñëè çàâåðøåí îáû÷íûì îáðàçîì, òî êàêîâ êîä çàâåðøåíèÿ),WTERMSIG (åñëè ïî ñèãíàëó, òî êàêîâ íîìåð ñèãíàëà).Áîëåå ãèáêèì ÿâëÿåòñÿ âûçîâint wait4(int pid, int *status, int options,struct rusage *rusage); êà÷åñòâå ïåðâîãî ïàðàìåòðà ìîæíî óêàçàòü èäåíòèôèêàòîð êîíêðåòíîãîïðîöåññà, ëèáî -1, åñëè òðåáóåòñÿ äîæäàòüñÿ ëþáîãî äî÷åðíåãî ïðîöåññà; èìååòñÿ òàêæå âîçìîæíîñòü äîæäàòüñÿ ïðîöåññà èç îïðåäåëåííîé ãðóïïû ïðîöåññîâ. Ïàðàìåòð status èñïîëüçóåòñÿ òàê æå, êàê äëÿ ïðåäûäóùåãî âûçîâà.
Âêà÷åñòâå çíà÷åíèÿ options ìîæíî óêàçàòü ÷èñëî 0, ëèáî êîíñòàíòó WNOHANG. ýòîì ñëó÷àå âûçîâ íå æäåò çàâåðøåíèÿ ïðîöåññîâ; åñëè íè îäíîãî ïîäõîäÿùåãî çîìáè íåò, âûçîâ íåìåäëåííî âîçâðàùàåò çíà÷åíèå 0. Åñëè óêàçàòåëü rusage íåíóëåâîé, â óêàçóåìóþ îáëàñòü ïàìÿòè çàïèñûâàþòñÿ çíà÷åíèÿñ÷åò÷èêîâ ðåñóðñîâ çàâåðøèâøåãîñÿ ïðîöåññà. Âûçîâ âîçâðàùàåò -1 â ñëó÷àåîøèáêè, 0 â ñëó÷àå, åñëè èñïîëüçîâàëàñü îïöèÿ WNOHANG è çàâåðøèâøèõñÿïðîöåññîâ íå áûëî, è pid çàâåðøèâøåãîñÿ ïðîöåññà, åñëè âûçîâ óñïåøíî ïîëó÷èë èíôîðìàöèþ èç çîìáè.14.2.5ÏðèìåðÏðèâåäåì ïðèìåð çàïóñêà âíåøíåé ïðîãðàììû ñ ïîìîùüþ ñâÿçêèfork()+exec().int pid;pid = fork();if(pid == -1) { /* îøèáêà */perror("fork");exit(1);94}if(pid == 0) { /* äî÷åðíèé ïðîöåññ */execlp("ls", "ls", "-l", "-a", "/var", NULL);perror("ls"); /* exec âåðíóë óïðàâëåíèå -> îøèáêà */exit(1); /* çàâåðøàåì ïðîöåññ ñ íåóñïåøíûì êîäîì */}/* ðîäèòåëüñêèé ïðîöåññ */wait(NULL); /* äîæäàåìñÿ îêîí÷àíèÿ äî÷åðíåãî ïðîöåññà,çàîäíî óáèðàåì çîìáè */14.3Æèçíåííûé öèêë ïðîöåññàблокировка(откачан)готовность(откачан)блокировкасозданиеготовностьядропольз.
режимпрерываниепланировщиквыполнениев режиме ядравыйзовынемстисгопроенммарепрzombieерратвозввыполнениеÐèñ. 20: Æèçíåííûé öèêë ïðîöåññàÑ ó÷åòîì âîçìîæíîñòè îòêà÷êè íåîáõîäèìûõ ïðîöåññó äàííûõ èç ïàìÿòèíà âíåøíèå óñòðîéñòâà, æèçíåííûé öèêë ïðîöåññà ïðèíèìàåò âèä, ïîêàçàííûé íà ðèñ. 20. Íà ñõåìå âèäíî, ÷òî ïðîöåññ ìîæåò áûòü ñîçäàí êàê ãîòîâûìê èñïîëíåíèþ (åñëè â ñèñòåìå áûëî äîñòàòî÷íî äëÿ ýòîãî ñâîáîäíîé îïåðàòèâíîé ïàìÿòè), òàê è ñðàçó îòêà÷àííûì, åñëè ïàìÿòè íå õâàòèëî.
Ñèñòåìàïî ñâîåìó óñìîòðåíèþ ìîæåò îòêà÷èâàòü è ïîäêà÷èâàòü îáðàòíî ïàìÿòü ãîòîâûõ ê âûïîëíåíèþ ïðîöåññîâ (êàê îòäåëüíûå ñòðàíèöû, òàê è ïðîöåññûöåëèêîì).95Ïðè çàïóñêå ïðîöåññà íà âûïîëíåíèå ÿäðî ñíà÷àëà âûïîëíÿåò íåêîòîðóþïîäãîòîâèòåëüíóþ ðàáîòó; âìåñòå ñ îáðàáîòêîé ñèñòåìíûõ âûçîâîâ è ïðîãðàììíûõ ïðåðûâàíèé ýòî ñîñòàâëÿåò âûïîëíåíèå â ðåæèìå ÿäðà. Âàæíîïîíèìàòü, ÷òî â ðåæèìå ÿäðà âûïîëíÿþòñÿ òîëüêî èíñòðóêöèè ÿäðà, íèêàêèå÷àñòè êîäà ïðîöåññà â ðåæèìå ÿäðà íèêîãäà íå èñïîëíÿþòñÿ. Íà ñàìîì äåëå,â ðåæèìå ÿäðà ðàáîòàåò, êàê ìû âèäèì, ñàìî ÿäðî.
Î âûïîëíåíèè ïðîöåññà âðåæèìå ÿäðà ãîâîðèòñÿ ëèøü ïîñòîëüêó, ïîñêîëüêó âðåìÿ, çàòðà÷èâàåìîå ÿäðîì íà ðàáîòó â èíòåðåñàõ äàííîãî ïðîöåññà, ó÷èòûâàåòñÿ êàê ïîòðåáëåííûéïðîöåññîì ðåñóðñ.Ïðîöåññ ìîæåò îêàçàòüñÿ ñíÿò ñ èñïîëíåíèÿ (ïåðåéòè â ñîñòîÿíèå ãîòîâíîñòè), ìèíóÿ ñòàäèþ âûïîëíåíèÿ â ðåæèìå ÿäðà.
Ýòî ìîæåò ïðîèçîéòè, åñëèÿäðî ïðèìåò ðåøåíèå î ñìåíå àêòèâíîãî ïðîöåññà âî âðåìÿ îáðàáîòêè àïïàðàòíîãî ïðåðûâàíèÿ (íàïðèìåð, ïðåðûâàíèÿ òàéìåðà). Âîçîáíîâëåíèå âûïîëíåíèÿ ïðîöåññà â ëþáîì ñëó÷àå òðåáóåò ïîäãîòîâèòåëüíûõ äåéñòâèé â ðåæèìåÿäðà.Ñòîèò îáðàòèòü âíèìàíèå íà òî, ÷òî ïðîöåññ, ïîïàâøèé â ðåæèì áëîêèðîâêè (íàïðèìåð, îæèäàþùèé ðåçóëüòàòîâ ââîäà-âûâîäà), ìîæåò êàê áûòüîòêà÷àí, òàê è îñòàâàòüñÿ â ïàìÿòè, åñëè îòêà÷êà ñèñòåìå íå ïîòðåáîâàëàñü.Îäíàêî, åñëè ïðîöåññ âñå æå áûë îòêà÷àí, îáðàòíàÿ ïîäêà÷êà áóäåò îñóùåñòâëåíà íå ðàíüøå, ÷åì ïðîöåññ îêàæåòñÿ ãîòîâ ê âûïîëíåíèþ (òî åñòü èñ÷åçíåòïðè÷èíà áëîêèðîâêè).15Ñèòóàöèÿ ãîíîê (race condition)Ðàññìîòðèì ïðîãðàììó, ïîðîæäàþùóþ äî÷åðíèé ïðîöåññ è âûäàþùóþäâà ñîîáùåíèÿ, îäíî èç ïîðîæäåííîãî ïðîöåññà, âòîðîå èç ðîäèòåëüñêîãî:int main(){if(fork() == 0) { /* äî÷åðíèé ïðîöåññ */printf("I'm the child\n");} else {/* ðîäèòåëüñêèé ïðîöåññ */printf("I'm the parent\n");}return 0;}Âîçìîæíî äâå ñèòóàöèè.
 ïåðâîé ñèòóàöèè äî÷åðíèé ïðîöåññ íå óñïåâàåòïî òåì èëè èíûì ïðè÷èíàì íà÷àòü èñïîëíåíèå äî òîãî, êàê ðîäèòåëüñêèé äîéäåò äî âûçîâà ôóíêöèè printf(). Íàïðèìåð, ñèñòåìå ìîãëî íå õâàòèòü ïàìÿòè è äî÷åðíèé ïðîöåññ áûë ñîçäàí â îòêà÷àííîì ñîñòîÿíèè (â ñâîï-ïàìÿòè). Â96ýòîì ñëó÷àå ñíà÷àëà áóäåò íàïå÷àòàíà ôðàçà I'm the parent, çàòåì − ôðàçàI'm the child.Ìîæåò ïîëó÷èòüñÿ è èíà÷å. Ê ïðèìåðó, ó ðîäèòåëüñêîãî ïðîöåññà ìîæåòñðàçó ïî âûïîëíåíèè âûçîâà fork() èñòå÷ü êâàíò âðåìåíè. Ïðè ýòîì äî÷åðíèé ïðîöåññ, êîòîðîìó íà ñåé ðàç õâàòèëî ïàìÿòè, ìîæåò ïîëó÷èòü óïðàâëåíèå è óñïåòü çà ñâîé êâàíò âðåìåíè ïðîèçâåñòè ïå÷àòü.
Òîãäà ôðàçû ïîÿâÿòñÿíà ýêðàíå â îáðàòíîì ïîðÿäêå.Ñèòóàöèè, â êîòîðûõ ðåçóëüòàò çàâèñèò îò êîíêðåòíîé ïîñëåäîâàòåëüíîñòè íåçàâèñèìûõ ñîáûòèé (îáû÷íî ñîáûòèé èç ðàáîòàþùèõ ïàðàëëåëüíî ïðîöåññîâ) íàçûâàþòñÿ ñèòóàöèÿìè ãîíîê 7 .Ñèòóàöèè ãîíîê ÷àñòî âîçíèêàþò â ïàðàëëåëüíîì ïðîãðàììèðîâàíèè, òîåñòü ïðè íàëè÷èè áîëåå ÷åì îäíîãî ïîòîêà óïðàâëåíèÿ. Îòíîñèòüñÿ ê âîçíèêíîâåíèþ òàêèõ ñèòóàöèé ñëåäóåò êðàéíå âíèìàòåëüíî, ïîñêîëüêó â íåêîòîðûõñëó÷àÿõ íåó÷òåííûå ñèòóàöèè ñîñòÿçàíèé ìîãóò ïðèâîäèòü ê îøèáêàì è äàæåïðîáëåìàì â áåçîïàñíîñòè.Ê ðàññìîòðåíèþ ñèòóàöèé ãîíîê ìû åùå âåðíåìñÿ â îäíîé èç ïîçäíèõëåêöèé.7 Ñîîòâåòñòâóþùèéàíãëîÿçû÷íûé òåðìèí − race condition.  ðóññêèõ ïåðåâîäàõ âñòðå÷àåòñÿ òàêæåñèòóàöèÿ ñîñòÿçàíèé.97Ëåêöèÿ 816Óïðàâëåíèå ñâîéñòâàìè ïðîöåññà16.1Òåêóùèé è êîðíåâîé êàòàëîãèÒåêóùèé êàòàëîã ìîæíî ñìåíèòü ñ ïîìîùüþ âûçîâàint chdir(const char* path);ïîäàâ â êà÷åñòâå ïàðàìåòðà ïîëíûé ïóòü íîâîãî êàòàëîãà ëèáî ïóòü îòíîñèòåëüíî òåêóùåãî êàòàëîãà.
Ñòðîêà ".." îçíà÷àåò êàòàëîã óðîâíåì âûøå îòíîñèòåëüíî çàäàííîãî (íàïðèìåð, /usr/local/share/.. − ýòî òî æå ñàìîå,÷òî /usr/local).Ñìåíà êîðíåâîãî êàòàëîãà îñóùåñòâëÿåòñÿ âûçîâîìint chroot(const char* path);Ïîñëå âûïîëíåíèÿ ýòîãî âûçîâà êàòàëîãè çà ïðåäåëîì íîâîãî êîðíåâîãî ïåðåñòàþò áûòü âèäíû èëè êàêèì-ëèáî îáðàçîì äîñòóïíû ïðîöåññó è âñåì åãîïîòîìêàì.
Îïåðàöèÿ ñìåíû êîðíåâîãî êàòàëîãà íåîáðàòèìà.Âûçîâ chroot() ìîãóò âûïîëíÿòü òîëüêî ïðîöåññû, èìåþùèå ïðàâà ïîëüçîâàòåëÿ root.16.2ÎêðóæåíèåÎêðóæåíèå äîñòóïíî â ïðîãðàììàõ íà C ÷åðåç ãëîáàëüíóþ ïåðåìåííóþextern char **environ;Äëÿ ìàíèïóëÿöèè ïåðåìåííûìè îêðóæåíèÿ ñëóæàò ôóíêöèèchar *getenv(const char *name);int setenv(const char *name, const char *value, int overwrite);void unsetenv(const char *name);Ôóíêöèÿ getenv() âîçâðàùàåò ñòðîêó, ÿâëÿþùóþñÿ çíà÷åíèåì ïåðåìåííîé,èìÿ êîòîðîé çàäàåòñÿ àðãóìåíòîì name. Åñëè òàêîé ïåðåìåííîé â îêðóæåíèèíåò, âîçâðàùàåòñÿ çíà÷åíèå NULL.Î÷åíü âàæíî ïðîèçâåñòè ïðîâåðêó íàNULLïåðåä àíàëèçîì âîçâðàùåííîé ñòðîêè. Íèêòîíå ìîæåò ãàðàíòèðîâàòü íàëè÷èå êàêîé áû òî íè áûëî ïåðåìåííîé â îêðóæåíèè ïðîöåññà, äàæååñëè ðå÷ü èäåò î ñòàíäàðòíûõ ïåðåìåííûõ, âêëþ÷àÿ98PATH.Ôóíêöèÿ setenv() óñòàíàâëèâàåò íîâîå çíà÷åíèå ïåðåìåííîé, ïðè÷åì åñëè òàêîé ïåðåìåííîé íå áûëî, çíà÷åíèå óñòàíàâëèâàåòñÿ â ëþáîì ñëó÷àå, åñëè æå ñîîòâåòñòâóþùàÿ ïåðåìåííàÿ â îêðóæåíèè óæå åñòü, íîâîå çíà÷åíèåóñòàíàâëèâàåòñÿ òîëüêî ïðè íåíóëåâîì çíà÷åíèè ïàðàìåòðà overwrite; òàêèìîáðàçîì, ïàðàìåòð overwrite ðàçðåøàåò èëè çàïðåùàåò èçìåíÿòü çíà÷åíèåïåðåìåííîé îêðóæåíèÿ, åñëè òàêîâàÿ óæå åñòü.Ôóíêöèÿ unsetenv() óäàëÿåò ïåðåìåííóþ ñ çàäàííûì èìåíåì èç îêðóæåíèÿ.16.3Ïàðàìåòð umaskÏàðàìåòð umask ìîæíî èçìåíèòü ñ ïîìîùüþ ñèñòåìíîãî âûçîâàint umask(int mask);Ýòîò ñèñòåìíûé âûçîâ âñåãäà çàâåðøàåòñÿ óñïåøíî è âîçâðàùàåò ïðåäûäóùååçíà÷åíèå ïàðàìåòðà umask.16.4Ìàíèïóëÿöèÿ òàáëèöåé äåñêðèïòîðîâÍîâûå ôàéëîâûå äåñêðèïòîðû ñîçäàþòñÿ ïðè óñïåøíîì âûïîëíåíèè âûçîâà open(), à òàêæå âî ìíîãèõ äðóãèõ ñëó÷àÿõ (êàê ìû óâèäèì íà ñëåäóþùèõ ëåêöèÿõ, äåñêðèïòîðû èñïîëüçóþòñÿ òàêæå äëÿ êàíàëîâ, ñîêåòîâ è ò.ï.)Ïðè ñîçäàíèè íîâîãî ôàéëîâîãî äåñêðèïòîðà ñèñòåìà âñåãäà âûáèðàåò íàèìåíüøèé ñâîáîäíûé íîìåð; òàê, åñëè çàêðûòü íóëåâîé äåñêðèïòîð, ñëåäóþùèé óñïåøíûé âûçîâ open() âåðíåò íîëü.Äëÿ çàêðûòèÿ äåñêðèïòîðà èñïîëüçóåòñÿ óæå ðàññìàòðèâàâøèéñÿ âûçîâclose().Êðîìå ýòîãî, î÷åíü âàæíû åùå äâà ñèñòåìíûõ âûçîâà, ñîçäàþùèå ñèíîíèìû ñóùåñòâóþùèõ äåñêðèïòîðîâ:int dup(int fd);int dup2(int fd, int new_fd);Âûçîâ dup() ñîçäàåò íîâûé ôàéëîâûé äåñêðèïòîð, ñâÿçàííûé ñ òåì æå ñàìûì ïîòîêîì ââîäà-âûâîäà, ÷òî è fd.
Íîâûé è ñòàðûé äåñêðèïòîðû ðàçäåëÿþò, â ÷èñëå ïðî÷åãî, è óêàçàòåëü òåêóùåé ïîçèöèè â ôàéëå: åñëè íà îäíîì èçíèõ ñìåíèòü ïîçèöèþ ñ ïîìîùüþ lseek(), ïîçèöèÿ íà âòîðîì èç íèõ òàêæåèçìåíèòñÿ.Âûçîâ dup2() îòëè÷àåòñÿ òåì, ÷òî íîâûé äåñêðèïòîð ñîçäàåòñÿ ïîä çàäàííûì íîìåðîì (ïàðàìåòð new_fd). Åñëè ýòîò íîìåð áûë ñâÿçàí ñ îòêðûòûìäåñêðèïòîðîì, òîò äåñêðèïòîð çàêðûâàåòñÿ.99Ðàññìîòðèì äëÿ ïðèìåðà ñèòóàöèþ, êîãäà íåêîòîðàÿ áèáëèîòåêà, êîòîðóþ ìû èñïîëüçóåì, ïðîèçâîäèò âûâîä íóæíîé íàì èíôîðìàöèè âñåãäà íàñòàíäàðòíûé ïîòîê âûâîäà, à íàì æåëàòåëüíî ñîîòâåòñòâóþùóþ èíôîðìàöèþ âûâåñòè â ôàéë. Ýòî ìîæíî ñäåëàòü ñ ïîìîùüþ òàêîãî ôðàãìåíòà êîäà:int save1, fd;fflush(stdout);/* íà âñÿêèé ñëó÷àé î÷èùàåì áóôåðñòàíäàðòíîãî âûâîäà */save1 = dup(1);/* ñîõðàíÿåì íàø ñòàíäàðòíûé âûâîä */int fd = open("file.dat", O_CREAT|O_WRONLY|O_TRUNC, 0666);/* îòêðûëè ôàéë */if(fd == -1) { /* ...
îáðàáîòêà îøèáêè ... */ }dup2(fd, 1);/* cäåëàëè îòêðûòûé ôàéëñòàíäàðòíûì ïîòîêîì âûâîäà */close(fd);/* çàêðûëè "ëèøíèé" äåñêðèïòîð *//* ... ïðîèçâîäèì äåéñòâèÿ ñ íàøåé áèáëèîòåêîé ...âñå ýòî âðåìÿ âûçîâû ôóíêöèé, ðàáîòàþùèõ ñî ñòàíäàðòíûìâûâîäîì (òàêèõ êàê printf, puts è ò.ï.), áóäóò âûâîäèòüèíôîðìàöèþ â íàø ôàéë*/dup2(save1, 1);close(save1);/* âîññòàíîâèëè ñòàðûé ñòàíäàðòíûéïîòîê âûâîäà *//* ôàéë ïðè ýòîì çàêðûëñÿ àâòîìàòè÷åñêè *//* ëèøíÿÿ êîïèÿ íàì íå íóæíà */Ðàññìîòðèì åùå îäèí ïðèìåð. Äîïóñòèì, ó íàñ âîçíèêëà ïîòðåáíîñòü âïðîãðàììå íà C ñìîäåëèðîâàòü ôóíêöèîíèðîâàíèå êîìàíäû Shellls -l -a -R / > filelist(ïîïðîñòó ãîâîðÿ, ñãåíåðèðîâàòü ôàéë filelist, ñîäåðæàùèé ñïèñîê âñåõôàéëîâ â ñèñòåìå). Ýòî ìîæíî ñäåëàòü ñ ïîìîùüþ ñëåäóþùåãî ôðàãìåíòà:int pid, status;pid = fork();if(pid == -1) { /* ...