А.В. Столяров - Введение в операционные системы (1152218), страница 24
Текст из файла (страница 24)
Ìû ìîãëè áû îñòàâèòü òåëî öèêëà106while ïóñòûì, íî ýòî ïðèâåëî áû ê âîçíèêíîâåíèþ àêòèâíîãî îæèäàíèÿ, àýòîãî ñëåäóåò ïî âîçìîæíîñòè èçáåãàòü, ò.ê. ïðè àêòèâíîì îæèäàíèè ïðîöåññîð îêàçûâàåòñÿ çàíÿò áåññìûñëåííîé ðàáîòîé.Ñëîâî volatile â îïèñàíèè ïåðåìåííîé i óêàçûâàåò êîìïèëÿòîðó, ÷òîçíà÷åíèå ïåðåìåííîé i ìîæåò íåîæèäàííî èçìåíèòüñÿ; ïðè îáðàáîòêå ïåðåìåííûõ, îïèñàííûõ êàê volatile, êîìïèëÿòîð íå ïðèáåãàåò ê ìåòîäàì îïòèìèçàöèè, îñíîâàííûì íà ïðåäïîëîæåíèÿõ î çíà÷åíèè òàêîé ïåðåìåííîé.Ñëåäóåò îáðàòèòü âíèìàíèå íà òî, ÷òî ðåæèì îáðàáîòêè ñèãíàëà SIGINTâûñòàâëÿåòñÿ êàê â íà÷àëå ïðîãðàììû, òàê è ïðè êàæäîì ïîëó÷åíèè ñèãíàëà;ýòî ñäåëàíî äëÿ òîãî, ÷òîáû ïðîãðàììà ðàáîòàëà êîððåêòíî â ñëó÷àå, åñëè ñèñòåìà, â êîòîðîé ìû åå çàïóñòèëè, ïîääåðæèâàåò êëàññè÷åñêóþ ñåìàíòèêóâûçîâà signal().Íàêîíåö, ÷èòàòåëü, âîçìîæíî, îáðàòèë âíèìàíèå, ÷òî âûâîä ñîîáùåíèÿPress it again, I like it ïðîèçâîäèòñÿ âûçîâîì write() âìåñòî ïðèâû÷íîãîprintf().
Äåëî â òîì, ÷òî èç îáðàáîò÷èêà ñèãíàëîâ îïàñíî âûçûâàòü ñëîæíûå ôóíêöèè: ñèãíàë ìîæåò ïðèéòè ïðîöåññó â òî âðåìÿ, êîãäà îí íàõîäèòñÿâíóòðè êàêîé-òî ôóíêöèè, è âíóòðåííèå ñòðóêòóðû äàííûõ ýòîé ôóíêöèè ïðèýòîì âðåìåííî îêàæóòñÿ â íåöåëîñòíîì ñîñòîÿíèè. Ïîñêîëüêó èç îáðàáîò÷èêàíèêàê íåëüçÿ îïðåäåëèòü, â êàêîé ìîìåíò áûëà ïðåðâàíà îñíîâíàÿ ïðîãðàììà, äàëüíåéøåå âìåøàòåëüñòâî â íåöåëîñòíûå ñòðóêòóðû äàííûõ ïðèâåäåòê íåïðåäñêàçóåìûì ïîñëåäñòâèÿì.
Ïðåæäå âñåãî ýòî êàñàåòñÿ äèíàìè÷åñêîéïàìÿòè, íî è áèáëèîòå÷íûå ôóíêöèè òèïà òîé æå printf() ìîãóò îêàçàòüñÿâ ýòîì ñìûñëå íåáåçîïàñíû.Âîîáùå, ñîãëàñíî ñòàíäàðòó, èç îáðàáîò÷èêà ñèãíàëà ìîæíî èçìåíÿòü ãëîáàëüíûå ïåðåìåííûå òèïà sig_atomic_t (íà ñàìîì äåëå ýòî îáû÷íî ñèíîíèìòèïà int) è âûçûâàòü ôóíêöèè èç ÿâíî ïåðå÷èñëåííûõ â ñïèñêå áåçîïàñíûõ.  èõ ÷èñëî âõîäèò è ôóíêöèÿ write(). Ïîëíûé ñïèñîê ìîæíî óçíàòüèç äîêóìåíòàöèè ïî âûçîâó signal(). çàêëþ÷åíèå îòìåòèì, ÷òî â ñîâðåìåííûõ ïðîãðàììàõ äëÿ óñòàíîâêè îáðàáîòêè ñèãíàëîâ îáû÷íî èñïîëüçóåòñÿ âûçîâsigaction(),à íåsignal().Ýòîò âûçîâ èìååò ñòàíäàðòíóþñåìàíòèêó âî âñåõ Unix-ïîäîáíûõ ñèñòåìàõ è ñóùåñòâåííî áîëåå ãèáîê. Ê ñîæàëåíèþ, åãî èñïîëüçîâàíèå òðåáóåò ôîðìèðîâàíèÿ äîñòàòî÷íî ñëîæíûõ ñòðóêòóð äàííûõ, à ïîäðîáíîå îïèñàíèå ôóíêöèîíàëüíîñòè îêàçûâàåòñÿ ãðîìîçäêèì è ïåðåãðóæåííûì òåõíè÷åñêèìè äåòàëÿìè.Ïîýòîìó âûçîâ18.4sigaction()ìû îñòàâëÿåì ÷èòàòåëþ äëÿ ñàìîñòîÿòåëüíîãî èçó÷åíèÿ.Ñèñòåìíûé âûçîâ alarm()Ñ ïîìîùüþ âûçîâà alarm() ìîæíî çàòðåáîâàòü îò ÿäðà îòïðàâêè íàøåìóïðîöåññó ñèãíàëà SIGALRM ÷åðåç îïðåäåëåííîå êîëè÷åñòâî ñåêóíä ðåàëüíîãîâðåìåíè.
Ïðîòîòèï âûçîâà òàêîâ:int alarm(unsigned int seconds);107Ïàðàìåòð çàäàåò êîëè÷åñòâî ñåêóíä, ÷åðåç êîòîðîå ñëåäóåò ïðèñëàòü ñèãíàë.Êàæäîìó ïðîöåññó â ñèñòåìå ìîæåò ñîîòâåòñòâîâàòü îäèí àêòèâíûé çàêàçíà îòïðàâêó SIGALRM; êîãäà çàêàçàííûé ïåðèîä âðåìåíè èñòåêàåò, ñèñòåìàïðèñûëàåò ïðîöåññó ñèãíàë, à ñàì àêòèâíûé çàêàç óíè÷òîæàåòñÿ.Âîçâðàùàåìîå âûçîâîì alarm() çíà÷åíèå çàâèñèò îò òîãî, èìååòñÿ ëè óæåäëÿ äàííîãî ïðîöåññà àêòèâíûé çàêàç íà îòïðàâêó SIGALRM. Åñëè òàêîãî íåáûëî, âûçîâ âîçâðàùàåò íîëü. Åñëè æå àêòèâíûé çàêàç óæå áûë, âîçâðàùåíîáóäåò êîëè÷åñòâî ñåêóíä, îñòàâøååñÿ äî ìîìåíòà åãî èñïîëíåíèÿ.Ñèñòåìà ìîæåò ïîìíèòü òîëüêî îá îäíîì ñèãíàëå SIGALRM, òàê ÷òî, åñëèïî ðåçóëüòàòàì ïðåäûäóùåãî âûçîâà ñèãíàë ïðèñëàòü ïðîöåññó íå óñïåëè,íîâûé âûçîâ îòìåíèò ñòàðûé çàêàç è óñòàíîâèò íîâûé.Îòìåòèì, ÷òî íóëåâîå çíà÷åíèå ïàðàìåòðà seconds îòìåíèò àêòèâíûé çàêàç, íå óñòàíîâèâ íîâûé.18.5Çàêëþ÷åíèåÍåñìîòðÿ íà êàæóùóþñÿ ïðîñòîòó, àêòèâíàÿ ðàáîòà ñ ñèãíàëàìè òðåáóåòâûñîêîé êâàëèôèêàöèè.
Ïðè èñïîëüçîâàíèè ñèãíàëîâ ÷àñòî âîçíèêàþò ñèòóàöèè ãîíîê, ñàìè ñèãíàëû íåíàäåæíû, ïðè îòïðàâêå äâóõ îäèíàêîâûõ ñèãíàëîâïðèéòè ìîæåò òîëüêî îäèí, è ò.ä.Åñëè ïðîöåññ, áëîêèðîâàííûé â ñèñòåìíîì âûçîâå, ïîëó÷àåò ñèãíàë, ðåæèì îáðàáîòêè êîòîðîãî îòëè÷àåòñÿ îò èãíîðèðîâàíèÿ (íàïðèìåð, óñòàíîâëåí îáðàáîò÷èê), òî ñèñòåìíûé âûçîâ, â êîòîðîì áûë áëîêèðîâàí ïðîöåññ(íàïðèìåð, read(), sleep() è äð.), âîçâðàùàåò óïðàâëåíèå, ñèãíàëèçèðóÿ îáîøèáêå; îò íàñòîÿùåé îøèáêè ýòó ñèòóàöèþ ìîæíî îòëè÷èòü ïî çíà÷åíèþïåðåìåííîé errno, êîòîðàÿ áóäåò ðàâíà EINTR.Òàêèì îáðàçîì, íàïèñàíèå êîððåêòíîé ïðîãðàììû, àêòèâíî èñïîëüçóþùåé ñèãíàëû, ìîæåò îêàçàòüñÿ äåëîì âåñüìà ñëîæíûì.19ÊàíàëûÊàíàë − ýòî îáúåêò ÿäðà, ïðåäñòàâëÿþùèé ñîáîé ñðåäñòâî îäíîíàïðàâëåííîé ïåðåäà÷è äàííûõ.
Êàíàë âñåãäà èìååò äâà êîíöà, îäèí äëÿ çàïèñè,äðóãîé äëÿ ÷òåíèÿ. Ñ êàæäûì êîíöîì êàíàëà ìîãóò áûòü ñâÿçàíû ôàéëîâûåäåñêðèïòîðû, ïðèíàäëåæàùèå, âîçìîæíî, ðàçíûì ïðîöåññàì.108Ðèñ. 22: Ñâÿçûâàíèå äâóõ äî÷åðíèõ ïðîöåññîâ ÷åðåç íåèìåíîâàííûé êàíàë19.119.1.1Íåèìåíîâàííûå êàíàëûÑîçäàíèå êàíàëàÍåèìåíîâàííûé êàíàë ñîçäàåòñÿ ñèñòåìíûì âûçîâîìint pipe(int fd[2]);Íà âõîä åìó ïîäàåòñÿ àäðåñ ìàññèâà èç äâóõ ýëåìåíòîâ òèïà int; â ýòîò ìàññèâ âûçîâ pipe() çàïèñûâàåò äåñêðèïòîðû, ñâÿçàííûå ñ ñîçäàííûì êàíàëîì:fd[0] − äëÿ ÷òåíèÿ, fd[1] − äëÿ çàïèñè.Êàê ÿñíî èç íàçâàíèÿ, òàêîé êàíàë íå èìååò èìåíè è, ñîîòâåòñòâåííî,íå ñóùåñòâóåò ñïîñîáà ïîäêëþ÷èòüñÿ ê òàêîìó êàíàëó èç äðóãîãî ïðîöåññà.Åäèíñòâåííûé ñïîñîá äîáèòüñÿ òîãî, ÷òîáû ê îäíîìó è òîìó æå êàíàëó îêàçàëèñü ïîäêëþ÷åíû ðàçíûå ïðîöåññû − ýòî ñîçäàòü êîïèþ ïðîöåññà, ñîçäàâøåãî êàíàë, ñ ïîìîùüþ âûçîâà fork().
Òàêèì îáðàçîì, èñïîëüçîâàòü íåèìåíîâàííûé êàíàë äëÿ âçàèìîäåéñòâèÿ ìåæäó ñîáîé ìîãóò òîëüêî ðîäñòâåííûåïðîöåññû, ÷åé îáùèé ïðåäîê ñîçäàë ñîîòâåòñòâóþùèé êàíàë.Íà ðèñ. 22 ïîêàçàíî ñâÿçûâàíèå ñ ïîìîùüþ íåèìåíîâàííîãî êàíàëà äâóõäî÷åðíèõ ïðîöåññîâ. Íà ïåðâîì øàãå (äî ïîðîæäåíèÿ íîâûõ ïðîöåññîâ) ðîäèòåëüñêèé ïðîöåññ ñîçäàåò êàíàë. Çàòåì ðîäèòåëüñêèé ïðîöåññ ïîðîæäàåòäâà äî÷åðíèõ ïðîöåññà, â ðåçóëüòàòå ÷åãî âî âñåõ òðåõ ïðîöåññàõ îêàçûâàþòñÿ äåñêðèïòîðû êàê îäíîãî, òàê è âòîðîãî êîíöîâ êàíàëà. Ïîñëå ýòîãîðîäèòåëüñêèé ïðîöåññ çàêðûâàåò ñâîè ýêçåìïëÿðû äåñêðèïòîðîâ, ÷òîáû íåìåøàòü äî÷åðíèì ïðîöåññàì èñïîëüçîâàòü êàíàë.
 ñâîþ î÷åðåäü, â ïåðâîìäî÷åðíåì ïðîöåññå çàêðûâàåòñÿ äåñêðèïòîð, ïðåäíàçíà÷åííûé äëÿ ÷òåíèÿ, âîâòîðîì − äëÿ çàïèñè.  ðåçóëüòàòå äî÷åðíèå ïðîöåññû îêàçûâàþòñÿ ñâÿçàíûòàêèì îáðàçîì, ÷òî ïåðâûé âòîðîìó ìîæåò ïåðåäàâàòü äàííûå ÷åðåç êàíàë.Ñîîòâåòñòâóþùèé êîä íà ÿçûêå C áóäåò âûãëÿäåòü ïðèáëèçèòåëüíî òàê:int fd[2];pipe(fd);if(fork()==0) { /* child #1 */close(fd[0]);109/* ... */write(fd[1], /* ..., */);/* ... */exit(0);}if(fork()==0) { /* child #2 */close(fd[1]);/* ... */rc = read(fd[0], /* ..., */);/* ... */exit(0);}/* parent */close(fd[0]);close(fd[1]);/* ... */19.1.2Ïîâåäåíèå êàíàëà â îñîáûõ ñëó÷àÿõÐàññìîòðèì äëÿ íà÷àëà ñèòóàöèþ, êîãäà â ñèñòåìå ïðèñóòñòâóþò îòêðûòûå äåñêðèïòîðû îáîèõ êîíöîâ êàíàëà.
Ïðè ïîïûòêå ÷òåíèÿ èç êàíàëà, âêîòîðûé ïîêà íèêòî íè÷åãî íå çàïèñàë, ÷èòàþùèé ïðîöåññ áóäåò çàáëîêèðîâàí (òî åñòü read() íå âåðíåò óïðàâëåíèå) äî òåõ ïîð, ïîêà ëèáî êòî-íèáóäüíå îñóùåñòâèò çàïèñü äàííûõ â êàíàë, ëèáî âñå äåñêðèïòîðû, îòêðûòûå íàçàïèñü â ýòîò êàíàë, íå îêàæóòñÿ çàêðûòû.Îòìåòèì, ÷òî, åñëè â êàíàëå äîñòóïíû äëÿ ÷òåíèÿ äàííûå (íåçàâèñèìî îòèõ êîëè÷åñòâà, õîòÿ áû îäèí áàéò), ôóíêöèÿ read() ïðè ïîïûòêå ÷òåíèÿ èçêàíàëà âåðíåò óïðàâëåíèå íåìåäëåííî; åñëè òðåòèé ïàðàìåòð read() (êîëè÷åñòâî áàéò, êîòîðîå ïðåäïèñûâàåòñÿ ïðî÷èòàòü) áûë áîëüøå, ÷åì íà ìîìåíòâûçîâà îêàçàëîñü äîñòóïíî äàííûõ, ïðî÷èòàíû áóäóò âñå äîñòóïíûå äàííûå,è read() âåðíåò èõ êîëè÷åñòâî, êîòîðîå ïðè ýòîì áóäåò ìåíüøå çàêàçàííîãî.Ïîïûòêè çàïèñè â êàíàë, èç êîòîðîãî íèêòî íå ÷èòàåò, íåêîòîðîå âðåìÿ áóäóò óñïåøíûìè. Äåëî â òîì, ÷òî êàíàë èìååò âíóòðåííèé áóôåð, ðàçìåð êîòîðîãî çàâèñèò îò ðåàëèçàöèè (òàê, â Linux îí îáû÷íî ñîñòàâëÿåò 4096áàéò).
Ïîñëå òîãî, êàê áóôåð îêàæåòñÿ çàïîëíåí, î÷åðåäíîé âûçîâ write()çàáëîêèðóåò ïðîöåññ äî òåõ ïîð, ïîêà êòî-íèáóäü íå íà÷íåò èç êàíàëà ÷èòàòü,îñâîáîäèâ, òàêèì îáðàçîì, ìåñòî â áóôåðå.Ðàññìîòðèì òåïåðü ñëó÷àè, êîãäà âñå äåñêðèïòîðû, ñâÿçàííûå ñ îäíèìèç êîíöîâ êàíàëà, îêàçàëèñü çàêðûòû.
ßñíî, ÷òî äàííûé êîíêðåòíûé êàíàë110áîëåå íèêîãäà íå óäàñòñÿ èñïîëüçîâàòü, ïîñêîëüêó ñïîñîáà âíîâü ñâÿçàòü äåñêðèïòîð ñ îäíèì èç êîíöîâ íåèìåíîâàííîãî êàíàëà â ñèñòåìå íåò.Åñëè îêàçàëèñü çàêðûòû âñå äåñêðèïòîðû, ÷åðåç êîòîðûå ìîæíî áûëî çàïèñûâàòü äàííûå â êàíàë, îïåðàöèè ÷òåíèÿ (âûçîâûread()) ñíà÷àëà îïóñòîøàò âíóòðåííèé áóôåð êàíàëà, à çàòåì áóäóòâîçâðàùàòü 0 (ñèòóàöèÿ êîíåö ôàéëà).Åñëè, íàîáîðîò, îêàçàëèñü çàêðûòû âñå äåñêðèïòîðû, ÷åðåç êîòîðûå ìîæíî áûëî èç êàíàëà ÷èòàòü, òî ïåðâàÿ æå ïîïûòêà çàïèñèâ êàíàë ïðèâåäåò ê òîìó, ÷òî ïîïûòàâøèéñÿ îñóùåñòâèòü çàïèñüïðîöåññ ïîëó÷èò ñèãíàë SIGPIPE.
Ïî óìîë÷àíèþ ýòîò ñèãíàë çàâåðøàåò ïðîöåññ. Âûçîâ write() ïðè ýòîì âîçâðàùàåò -1, ÷òî ìîæåò áûòüîáíàðóæåíî òîëüêî â ñëó÷àå, åñëè ïðîöåññ ïåðåõâàòûâàåò èëè èãíîðèðóåòñèãíàë SIGPIPE.19.2Èñïîëüçîâàíèå íåèìåíîâàííûõ êàíàëîâ äëÿ ïîñòðîåíèÿ êîíâåéåðîâÊîíâåéåðîì íàçûâàåòñÿ ñïîñîá çàïóñêà íåñêîëüêèõ ïðîãðàìì, ïðè êîòîðîì èíôîðìàöèÿ, âûäàâàåìàÿ ïåðâîé ïðîãðàììîé íà ñòàíäàðòíûé âûâîä, ïîñòóïàåò âòîðîé ïðîãðàììå íà ñòàíäàðòíûé ââîä, âûâîä âòîðîé ïðîãðàììû −íà ââîä òðåòüåé ïðîãðàììå è ò.ä. Ìû óæå âñòðå÷àëèñü ñ êîíâåéåðàìè ïðèîáñóæäåíèè âîçìîæíîñòåé êîìàíäíîãî èíòåðïðåòàòîðà ÎÑ Unix.Îáû÷íî êîíâåéåðû ðåàëèçóþòñÿ ñ ïîìîùüþ íåèìåíîâàííûõ êàíàëîâ. Äëÿýòîãî íåîáõîäèìî ñîîòâåòñòâóþùèì îáðàçîì ñâÿçàòü ïîòîêè ñòàíäàðòíîãîââîäà è âûâîäà (òî åñòü äåñêðèïòîðû 0 è 1) â ïðîöåññàõ, ñîñòàâëÿþùèõ êîíâåéåð, ñ êîíöàìè êàíàëà.Î÷åíü âàæíî ïðè ýòîì çàêðûòü âñå ëèøíèå äåñêðèïòîðû, ñâÿçàííûå ñäàííûì êàíàëîì, âî âñåõ ïðîöåññàõ, âîâëå÷åííûõ â ðåøåíèå çàäà÷è.