А.В. Столяров - Введение в операционные системы (1152218), страница 23
Текст из файла (страница 23)
Ïðè íåîáõîäèìîñòè, ôóíêöèîíàëüíîñòü òåðìèíàëà êàê óñòðîéñòâà ìîæåò èìèòèðîâàòüïîëüçîâàòåëüñêèé ïðîöåññ (òàê ðàáîòàåò, íàïðèìåð, ïðîãðàììà xterm, à òàêæå ñåðâåðû, îòâå÷àþùèå çà óäàëåííûé äîñòóï ê ìàøèíå, òàêèå êàê sshd èëètelnetd). Âçàèìîäåéñòâèå òàêîãî ïðîöåññà ñ ïðîöåññàìè, äëÿ êîòîðûõ èìèòèðóåìûé (òî åñòü ïðîãðàììíî ðåàëèçîâàííûé) òåðìèíàë ÿâëÿåòñÿ óïðàâëÿþùèì, íàçûâàåòñÿ âçàèìîäåéñòâèåì ÷åðåç âèðòóàëüíûé òåðìèíàë.Íåñêîëüêî îñîáîå ìåñòî â êëàññèôèêàöèè çàíèìàþò ñðåäñòâà, îáúåäèíåííûå îáùèì íàçâàíèåì System V IPC 3 .
Ýòè ñðåäñòâà âêëþ÷àþò ìåõàíèçìûñîçäàíèÿ ðàçäåëÿåìîé ïàìÿòè, ìàññèâîâ ñåìàôîðîâ è î÷åðåäåé ñîîáùåíèé.Ñëåäóåò îòìåòèòü, ÷òî â ïðàêòè÷åñêîì ïðîãðàììèðîâàíèè System V IPC èñ2 Ýòîíå îñíîâíàÿ ôóíêöèîíàëüíîñòü mmap(). Èçíà÷àëüíî âûçîâ ïðåäíàçíà÷åí äëÿ îòîáðàæåíèÿ ñîäåðæèìîãî ôàéëîâ â âèðòóàëüíîå àäðåñíîå ïðîñòðàíñòâî ïðîöåññîâ.3 Ñèìâîë V â äàííîì ñëó÷àå îçíà÷àåò ðèìñêîå ïÿòü; òåðìèí ÷èòàåòñÿ êàê ñèñòýì ôàéâ àé-ïè-ñè102ïîëüçóåòñÿ ñðàâíèòåëüíî ðåäêî. Ýðèê Ðåéìîíä â êíèãå [3] íàçûâàåò ýòè ñðåäñòâà óñòàðåâøèìè.Îñíîâíûì ñðåäñòâîì âçàèìîäåéñòâèÿ ÷åðåç êîìïüþòåðíóþ ñåòü (òîåñòü âçàèìîäåéñòâèÿ ïðîöåññîâ, íàõîäÿùèõñÿ â ðàçíûõ ñèñòåìàõ), ÿâëÿþòñÿ ñîêåòû (sockets).
Ñîêåòû ïðåäñòàâëÿþò ñîáîé óíèâåðñàëüíûé ìåõàíèçì,ïðèãîäíûé äëÿ ðàáîòû ñ øèðîêèì ñïåêòðîì ïðîòîêîëîâ; ýòî îçíà÷àåò, ÷òîîáëàñòü ïðèìåíåíèÿ ñîêåòîâ íå îãðàíè÷åíà ñåòÿìè íà îñíîâå TCP/IP èëèêàêîãî-ëèáî äðóãîãî ñòàíäàðòà; áîëåå òîãî, ïðè äîáàâëåíèè â ñèñòåìó ïîääåðæêè íîâûõ ïðîòîêîëîâ íåò íåîáõîäèìîñòè èçìåíÿòü èíòåðôåéñû ñèñòåìíûõ âûçîâîâ. Ðåàëèçàöèÿ ñîêåòîâ â ÎÑ Unix ïîääåðæèâàåò òàêæå ñïåöèàëüíûé âèä ïðîòîêîëà, êîòîðûé ìîæíî èñïîëüçîâàòü âíóòðè îäíîé ñèñòåìû, äàæå åñëè ïîääåðæêà êîìïüþòåðíûõ ñåòåé â ñèñòåìå îòñóòñòâóåò.Ñóùåñòâóþò è äðóãèå ñðåäñòâà âçàèìîäåéñòâèÿ ïî ñåòè, íî èñïîëüçóþòñÿîíè â íàñòîÿùåå âðåìÿ êðàéíå ðåäêî è â íàøåì êóðñå ðàññìàòðèâàòüñÿ íåáóäóò.1818.1ÑèãíàëûÏðåäíàçíà÷åíèå íåêîòîðûõ ñèãíàëîâÎäèí èç ïðîñòåéøèõ ñïîñîáîâ ïîâëèÿòü íà ðàáîòó ïðîöåññà − ýòî îòïðàâèòü åìó ñèãíàë èç íåêîòîðîãî ïðåäîïðåäåëåííîãî ìíîæåñòâà.Èçíà÷àëüíî ñèãíàëû áûëè ïðåäíàçíà÷åíû äëÿ ñíÿòèÿ ïðîöåññîâ ñ âûïîëíåíèÿ, íî ñ ðàçâèòèåì ñèñòåìû ïðèîáðåëè äðóãèå ôóíêöèè. Ïåðå÷èñëèì íåêîòîðûå íàèáîëåå óïîòðåáèòåëüíûå ñèãíàëû:• SIGTERM ïðåäïèñûâàåò ïðîöåññó çàâåðøèòüñÿ.
Ïðîöåññ ìîæåò ïåðåõâàòèòü èëè èãíîðèðîâàòü ýòîò ñèãíàë.• SIGKILL óíè÷òîæàåò ïðîöåññ.  îòëè÷èå îò SIGTERM, ýòîò ñèãíàë íèïåðåõâàòèòü, íè èãíîðèðîâàòü íåëüçÿ. Íåëèøíèì áóäåò çàïîìíèòü, ÷òî ñèãíàëSIGKILLèìååò íîìåð 9.Ðàçäåëåíèå óíè÷òîæàþùèõ ñèãíàëîâ íà ïåðåõâàòûâàåìûé è íåïåðåõâàòûâàåìûé ââåäåíî ñ öåëüþ ñîçäàíèÿ áîëåå ãèáêîé ïðîöåäóðû ñíÿòèÿïðîöåññîâ. Òàê, ïðè ïåðåçàãðóçêå ñèñòåìû âñåì ïðîöåññàì ðàññûëàåòñÿñíà÷àëà SIGTERM, à çàòåì, ÷åðåç 5 ñåêóíä − SIGKILL.
Ýòî ïîçâîëÿåò ïðîöåññàì ïðèâåñòè ñâîè äåëà â ïîðÿäîê: íàïðèìåð, ðåäàêòîð òåêñòîâ ìîæåò ñîõðàíèòü íåñîõðàíåííûé ðåäàêòèðóåìûé òåêñò âî âðåìåííîì ôàéëå ñ òåì, ÷òîáû ïîòîì (â íà÷àëå ñëåäóþùåãî ñåàíñà ðåäàêòèðîâàíèÿ)ïðåäëîæèòü ïîëüçîâàòåëþ âîññòàíîâèòü íåñîõðàíåííûå èçìåíåíèÿ.• SIGILL, SIGSEGV, SIGFPE è SIGBUS ñèñòåìà îòïðàâëÿåò ïðîöåññàì, ÷üèäåéñòâèÿ ïðèâåëè ê âîçíèêíîâåíèþ ïðîãðàììíîãî ïðåðûâàíèÿ (ñîîò103âåòñòâåííî, ïîïûòêà âûïîëíèòü íåñóùåñòâóþùóþ èëè íåäîïóñòèìóþêîìàíäó ïðîöåññîðà, íàðóøåíèå çàùèòû ïàìÿòè, äåëåíèå íà íîëü è îáðàùåíèå ê ïàìÿòè ïî íåêîððåêòíîìó àäðåñó). Ïî óìîë÷àíèþ ëþáîé èçýòèõ ñèãíàëîâ óíè÷òîæàåò ïðîöåññ ñ ñîçäàíèåì core-ôàéëà4 äëÿ ïîñëåäóþùåãî àíàëèçà ïðè÷èí ïðîèñøåñòâèÿ.
Îäíàêî ëþáîé èç ýòèõ ñèãíàëîâ ìîæíî ïåðåõâàòèòü (íàïðèìåð, ÷òîáû ïîïûòàòüñÿ ïåðåä çàâåðøåíèåì çàïèñàòü â ôàéë ðåçóëüòàòû ðàáîòû).SIGSTOP è SIGCONT ïîçâîëÿþò, ñîîòâåòñòâåííî, ïðèîñòàíîâèòü è ïðîäîëæèòü âûïîëíåíèå ïðîöåññà. Îòìåòèì, ÷òî SIGSTOP, êàê è SIGKILL,íåëüçÿ íè ïåðåõâàòèòü, íè èãíîðèðîâàòü. SIGCONT ïåðåõâàòèòü ìîæíî,íî ñâîþ îñíîâíóþ ôóíêöèþ (ïðîäîëæèòü âûïîëíåíèå ïðîöåññà) îí âûïîëíÿåò â ëþáîì ñëó÷àå.SIGINT è SIGQUIT îòïðàâëÿþòñÿ îñíîâíîé ãðóïïå ïðîöåññîâ äàííîãîòåðìèíàëà5 ïðè íàæàòèè íà êëàâèàòóðå êîìáèíàöèé Ctrl+C è Ctrl-\,ñîîòâåòñòâåííî. Ïî óìîë÷àíèþ îáà ñèãíàëà ïðèâîäÿò ê çàâåðøåíèþ ïðîöåññà, ïðè÷åì SIGQUIT åùå è ñîçäàåò core-ôàéë.SIGCHLD ñèñòåìà ïðèñûëàåò ðîäèòåëüñêîìó ïðîöåññó ïðè çàâåðøåíèèäî÷åðíåãî.SIGALRM ïðèñûëàåòñÿ ïî èñòå÷åíèè çàäàííîãî èíòåðâàëà âðåìåíè ïîñëåâûçîâà alarm().
Òàêèì îáðàçîì ïðîöåññ ìîæåò âçâåñòè äëÿ ñåáÿ íàïîìèíàíèå, íàïðèìåð, íà ñëó÷àé ÷ðåçìåðíî äîëãîãî âûïîëíåíèÿ òåõ èëèèíûõ äåéñòâèé. Îòïðàâèòåëåì ýòîãî ñèãíàëà îáû÷íî ÿâëÿåòñÿ îïåðàöèîííàÿ ñèñòåìà.SIGUSR1 è SIGUSR2 ïðåäíàçíà÷åíû äëÿ èñïîëüçîâàíèÿ ïðîãðàììèñòîìäëÿ ñâîèõ öåëåé. Îòìåòèì, ÷òî ïî óìîë÷àíèþ ýòè ñèãíàëû òàêæå çàâåðøàþò ïðîöåññ.•••••18.2Îòïðàâêà ñèãíàëàÎòïðàâèòåëåì ñèãíàëà ìîæåò áûòü êàê ïðîöåññ, òàê è îïåðàöèîííàÿ ñèñòåìà, ïîëó÷àòåëåì − âñåãäà ïðîöåññ.Äëÿ îòïðàâêè ñèãíàëà ñëóæèò ñèñòåìíûé âûçîâint kill(int target_pid, int sig_no);4 Core-ôàéë− ýòî ôàéë ñ èìåíåì core èëè prog.core, ñîçäàâàåìûé îïåðàöèîííîé ñèñòåìîé â òåêóùåìêàòàëîãå ïðè àâàðèéíîì çàâåðøåíèè ïðîãðàììû.  ýòîò ôàéë ïîëíîñòüþ çàïèñûâàåòñÿ ñîäåðæèìîå ñåãìåíòîâ äàííûõ è ñòåêà íà ìîìåíò àâàðèè. Core-ôàéëû ïîçâîëÿþò ñ ïîìîùüþ îòëàä÷èêà ïðîàíàëèçèðîâàòüïðè÷èíû àâàðèè, â òîì ÷èñëå − óçíàòü òî÷êó êîäà, â êîòîðîé ïðîèçîøëà àâàðèÿ, ïðîñìîòðåòü çíà÷åíèÿïåðåìåííûõ íà ìîìåíò àâàðèè è ò.ä.5 Ñåàíñû è ãðóïïû ïðîöåññîâ áóäóò ðàññìîòðåíû â íàøåì êóðñå ïîçæå.
Ïîêà ìîæíî ñ÷èòàòü, ÷òî ñèãíàëû SIGINT è SIGQUIT ïðè íàæàòèè ñîîòâåòñòâóþùèõ êëàâèø ïîëó÷àåò òîò ïðîöåññ, êîòîðûé âû ñàìèçàïóñòèëè, íàáðàâ êîìàíäó, à òàêæå åãî ïîòîìêè (åñëè îíè íå ïðåäïðèíÿëè ñïåöèàëüíûõ ìåð).104Ïàðàìåòð sig_no çàäàåò íîìåð ïîäëåæàùåãî îòïðàâêå ñèãíàëà. Äëÿ ëó÷øåéÿñíîñòè ïðîãðàììû ðåêîìåíäóåòñÿ èñïîëüçîâàòü âìåñòî ÷èñåë ìàêðîêîíñòàíòû ñ ïðåôèêñîì SIG, òàêèå êàê SIGINT, SIGUSR1 è ò.ï.Ïàðàìåòð target_pid çàäàåò ïðîöåññ(û) êîòîðîìó (êîòîðûì) ñëåäóåò îòïðàâèòü ñèãíàë.
Åñëè â êà÷åñòâå ýòîãî ïàðàìåòðà ïåðåäàòü ïîëîæèòåëüíîå÷èñëî, ýòî ÷èñëî áóäåò èñïîëüçîâàòüñÿ êàê íîìåð ïðîöåññà, êîòîðîìó ñëåäóåòïîñëàòü ñèãíàë. Åñëè ïåðåäàòü ÷èñëî -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() ïðèîñòàíàâëèâàåò âûïîëíåíèå ïðîãðàììûäî ïîëó÷åíèÿ íåèãíîðèðóåìîãî ñèãíàëà.