А.В. Столяров - Введение в операционные системы (1114673), страница 23
Текст из файла (страница 23)
Åñëè â êà÷åñòâå ýòîãî ïàðàìåòðà ïåðåäàòü ïîëîæèòåëüíîå÷èñëî, ýòî ÷èñëî áóäåò èñïîëüçîâàòüñÿ êàê íîìåð ïðîöåññà, êîòîðîìó ñëåäóåòïîñëàòü ñèãíàë. Åñëè ïåðåäàòü ÷èñëî -1, ñèãíàë áóäåò ïîñëàí âñåì ïðîöåññàì,êðîìå ñàìîãî âûçâàâøåãî kill(). Îòðèöàòåëüíîå ÷èñëî, áîëüøåå åäèíèöûïî ìîäóëþ, îçíà÷àåò ïåðåäà÷ó ñèãíàëà ãðóïïå ïðîöåññîâ ñ ñîîòâåòñòâóþùèìíîìåðîì. Íîëü îçíà÷àåò ïåðåäà÷ó ñèãíàëà âñåì ïðîöåññàì ñâîåé ãðóïïû.Ïðîöåññû, èìåþùèå ïîëíîìî÷èÿ ñóïåðïîëüçîâàòåëÿ (uid == 0), ìîãóòîòïðàâëÿòü ñèãíàëû ëþáûì ïðîöåññàì; âñå ïðî÷èå ïðîöåññû èìåþò ïðàâîîòïðàâêè ñèãíàëà òîëüêî ïðîöåññàì, ïðèíàäëåæàùèì òîìó æå ïîëüçîâàòåëþ.
Òàêèì îáðàçîì, äëÿ íåïðèâèëåãèðîâàííîãî ïðîöåññà âûçîâ kill(-1,SIGTERM) îçíà÷àåò îòïðàâêó ñèãíàëà SIGTERM âñåì ïðîöåññàì òîãî æå ïîëüçîâàòåëÿ, êðîìå ñàìîãî ñåáÿ.18.3Îáðàáîòêà ñèãíàëîâÅñëè íå ïðåäïðèíÿòü ñïåöèàëüíûõ ìåð, áîëüøèíñòâî ñèãíàëîâ çàâåðøàþòïðîöåññ, ïðè÷åì íåêîòîðûå èç íèõ åùå è ñîçäàþò core-ôàéë, ñîäåðæàùèé ñåãìåíò äàííûõ è ñòåêà çàâåðøåííîãî ïðîöåññà. Íåêîòîðûå ñèãíàëû (íàïðèìåð,SIGCHLD) ïî óìîë÷àíèþ èãíîðèðóþòñÿ.Ïðîöåññ ìîæåò äëÿ ëþáîãî ñèãíàëà, êðîìå SIGKILL è SIGSTOP, óñòàíîâèòüñâîé ðåæèì îáðàáîòêè: âûçîâ ôóíêöèè-îáðàáîò÷èêà, èãíîðèðîâàíèå èëè îáðàáîòêà ïî óìîë÷àíèþ.Ôóíêöèÿ-îáðàáîò÷èê äîëæíà ïðèíèìàòü îäèí öåëî÷èñëåííûé ïàðàìåòð èèìåòü òèï âîçâðàùàåìîãî çíà÷åíèÿ void, ò.å. ýòî äîëæíà áûòü ôóíêöèÿ âèäàvoid handler(int s) {/* ...
*/}Äëÿ óñòàíîâêè îáðàáîò÷èêà ñèãíàëà ìîæíî èñïîëüçîâàòü ñèñòåìíûé âûçîâsignal():typedef void (*sighandler_t)(int);sighandler_t signal(int signo, sighandler_t hdl);Ïàðàìåòð signo çàäàåò íîìåð ñèãíàëà, ïàðàìåòð hdl − àäðåñ ôóíêöèè, êîòîðàÿ äîëæíà áûòü âûçâàíà ïðè ïîëó÷åíèè ñîîòâåòñòâóþùåãî ñèãíàëà.  êà÷åñòâå çíà÷åíèÿ hdl òàêæå ìîæíî èñïîëüçîâàòü ñïåöèàëüíûå çíà÷åíèÿ SIG_IGN(èãíîðèðîâàòü ñèãíàë) è SIG_DFL (óñòàíîâèòü îáðàáîòêó ïî óìîë÷àíèþ).105Âûçîâ signal() âîçâðàùàåò çíà÷åíèå, ñîîòâåòñòâóþùåå ïðåäûäóùåìó ðåæèìó îáðàáîòêè äëÿ äàííîãî ñèãíàëà, ëèáî SIG_ERR â ñëó÷àå îøèáêè.Ïîñëå óñòàíîâêè ôóíêöèè-îáðàáîò÷èêà â ñëó÷àå, åñëè êòî-ëèáî îòïðàâèòíàøåìó ïðîöåññó ñèãíàë, áóäåò âûçâàíà ôóíêöèÿ-îáðàáîò÷èê (ñ ïàðàìåòðîì,ðàâíûì íîìåðó ñèãíàëà).Äàëüíåéøåå ïîâåäåíèå ïðîöåññà ïîñëå ïîëó÷åíèÿ ïåðâîãî ñèãíàëà çàâèñèò îò âåðñèè îïåðàöèîííîé ñèñòåìû (à èíîãäà, êàê â ñëó÷àåLinux, è îò âåðñèè ñèñòåìíûõ áèáëèîòåê).  êëàññè÷åñêèõ âåðñèÿõ Unix, âòîì ÷èñëå â System V, ðåæèì îáðàáîòêè ñèãíàëà ïðè ïîëó÷åíèè òàêîâîãî (èïåðåä ïåðåäà÷åé óïðàâëåíèÿ ôóíêöèè-îáðàáîò÷èêó) ñáðàñûâàëñÿ â ðåæèì ïîóìîë÷àíèþ.
 âåðñèÿõ BSD, íàïðîòèâ, ðåæèì îáðàáîòêè îñòàâàëñÿ ïðåæíèì,íî íà âðåìÿ ðàáîòû îáðàáîò÷èêà ñèãíàëû ñ òåì æå íîìåðîì áëîêèðîâàëèñü.×òîáû íàïèñàííàÿ ïðîãðàììà âåëà ñåáÿ áîëåå-ìåíåå îäèíàêîâî ïðè ëþáîìèç äâóõ âàðèàíòîâ ïîâåäåíèÿ, ñëåäóåò ïåðåóñòàíàâëèâàòü ðåæèì îáðàáîòêèêàæäûé ðàç â íà÷àëå ôóíêöèè-îáðàáîò÷èêà (ëèáî, íàîáîðîò, ñáðàñûâàòü ðåæèì îáðàáîòêè â SIG_DFL, åñëè òðåáóåòñÿ ïåðåõâàòèòü òîëüêî îäèí ñèãíàë).Íàïèøåì äëÿ ïðèìåðà ïðîãðàììó, êîòîðàÿ ïðè íàæàòèè Ctrl-C ñíà÷àëàâûäàåò ñîîáùåíèå, è ëèøü íà 25é ðàç çàâåðøàåòñÿ.#include <signal.h>#include <stdlib.h>volatile static int i = 0;const char message[] = "Press it again, I like it\n";void handler(int) {signal(SIGINT, handler);i++;write(1, message, sizeof(message)-1);}int main() {signal(SIGINT, handler);while(i<25) pause(); /* íå âûõîäèì èç ïðîãðàììû,æäåì ñèãíàëîâ */return 0;}Ïîÿñíèì, ÷òî ôóíêöèÿ pause() ïðèîñòàíàâëèâàåò âûïîëíåíèå ïðîãðàììûäî ïîëó÷åíèÿ íåèãíîðèðóåìîãî ñèãíàëà.
Ìû ìîãëè áû îñòàâèòü òåëî öèêëà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Ïîâåäåíèå êàíàëà â îñîáûõ ñëó÷àÿõÐàññìîòðèì äëÿ íà÷àëà ñèòóàöèþ, êîãäà â ñèñòåìå ïðèñóòñòâóþò îòêðûòûå äåñêðèïòîðû îáîèõ êîíöîâ êàíàëà.