А.В. Столяров - Введение в операционные системы (1152218), страница 25
Текст из файла (страница 25)
Ïðîãðàììû â ÎÑ Unix, êàê ïðàâèëî, ïèøóòñÿ òàê, ÷òîáû ðàáîòàòü äî âîçíèêíîâåíèÿñèòóàöèè êîíåö ôàéëà íà ïîòîêå ñòàíäàðòíîãî ââîäà; òàêàÿ ñèòóàöèÿ ìîæåò âîçíèêíóòü íà êàíàëå òîëüêî â ñëó÷àå, åñëè âñå äåñêðèïòîðû çàïèñèîêàæóòñÿ çàêðûòû. Òàêèì îáðàçîì, íàëè÷èå ëèøíåãî îòêðûòîãî äåñêðèïòîðà çàïèñè íàðóøèò íîðìàëüíóþ ðàáîòó êîíâåéåðà. Ñ äðóãîé ñòîðîíû, ïîñëåèñ÷åçíîâåíèÿ ïðîöåññà, äëÿ êîòîðîãî ïðåäíàçíà÷åíû ãåíåðèðóåìûå ïðîãðàììîé äàííûå, ïðîäîëæåíèå âûïîëíåíèÿ ïðîãðàììû îáû÷íî áåññìûñëåííî. Åñëè ñ èñ÷åçíîâåíèåì ñëåäóþùåãî ýëåìåíòà êîíâåéåðà çàêðîåòñÿ ïîñëåäíèéäåñêðèïòîð, îòêðûòûé íà ÷òåíèå èç êàíàëà, òî ïèøóùèé ïðîöåññ áóäåò ñíÿòñèãíàëîì SIGPIPE.
Åñëè æå ãäå-òî îñòàíåòñÿ åùå õîòÿ áû îäèí îòêðûòûéäåñêðèïòîð äëÿ ÷òåíèÿ, ïðîöåññ áóäåò ïðîñòî çàáëîêèðîâàí; âîçìîæíî, ýòîáëîêèðóåò âûïîëíåíèå åùå êàêèõ-òî çàäà÷, êîòîðûå äîæèäàþòñÿ çàâåðøåíèÿ111ýòîãî ïðîöåññà.Ðàññìîòðèì äëÿ ïðèìåðà êîíâåéåðls -lR| grep '^d'Ïðîãðàììà íà C, âûïîëíÿþùàÿ òå æå äåéñòâèÿ, áóäåò âûãëÿäåòü òàê:int main() {int fd[2];pipe(fd);/* ñîçäàåì êàíàë äëÿ ñâÿçè */if(fork()==0) { /* ïðîöåññ äëÿ âûïîëíåíèÿ ls -lR */close(fd[0]); /* ÷èòàòü èç êàíàëà íå íóæíî */dup2(fd[1], 1); /* ñòàíä. âûâîä - â êàíàë */close(fd[1]); /* fd[1] áîëüøå íå íóæåí *//* çàïóñêàåì ls -lR */execlp("ls", "ls", "-lR", NULL);/* íå ïîëó÷èëîñü, ñîîáùàåì îá îøèáêå */perror("ls");exit(1);}if(fork()==0) { /* ïðîöåññ äëÿ âûïîëíåíèÿ grep */close(fd[1]); /* ïèñàòü â êàíàë íå íóæíî */dup2(fd[0], 0); /* ñòàíä.
ââîä - èç êàíàëà */close(fd[0]); /* fd[0] áîëüøå íå íóæåí *//* çàïóñêàåì grep */execlp("grep", "grep", "^d", NULL);/* íå ïîëó÷èëîñü, ñîîáùàåì îá îøèáêå */perror("grep");exit(1);}/* â ðîäèòåëüñêîì ïðîöåññå çàêðûâàåì îáàêîíöà êàíàëà */close(fd[0]); close(fd[1]);/* äîæèäàåìñÿ çàâåðøåíèÿ îáîèõ ïîòîìêîâ */wait(NULL); wait(NULL);return 0;}19.3Èìåíîâàííûå êàíàëû (FIFO)Èìåíîâàííûå êàíàëû ïî ñóòè ïîäîáíû íåèìåíîâàííûì, ñ òîé ðàçíèöåé,÷òî èìåíîâàííîìó êàíàëó ñîîòâåòñòâóåò ôàéë ñïåöèàëüíîãî òèïà (FIFO), ðàç112ìåùàåìûé â ôàéëîâîé ñèñòåìå.
Òàêèì îáðàçîì, ê èìåíîâàííîìó êàíàëó ìîãóò ïðèñîåäèíÿòüñÿ ïðîöåññû, íå èìåþùèå ðîäñòâåííûõ ñâÿçåé; áîëåå òîãî,çàêðûòèå âñåõ äåñêðèïòîðîâ, îòâå÷àþùèõ çà ÷òåíèå èç òàêîãî êàíàëà èëèçà çàïèñü â òàêîé êàíàë åùå íå îçíà÷àåò, ÷òî êàíàë áîëåå íå ïðèãîäåí äëÿðàáîòû, ò.ê. â ëþáîé ìîìåíò òàêèå äåñêðèïòîðû ìîãóò ïîÿâèòüñÿ âíîâü.Äëÿ ñîçäàíèÿ ôàéëà FIFO èñïîëüçóåòñÿ ôóíêöèÿint mkfifo(const char *pathname, int permissions);Ïåðâûé ïàðàìåòð çàäàåò èìÿ ôàéëà, âòîðîé − ïðàâà äîñòóïà ê íåìó (àíàëîãè÷íî âûçîâàì open() è mkdir()). Ïðàâà, åñòåñòâåííî, ìîäèôèöèðóþòñÿïàðàìåòðîì umask. Ôóíêöèÿ âîçâðàùàåò -1 â ñëó÷àå îøèáêè, 0 − â ñëó÷àåóñïåõà.Ïðè ñîçäàíèè ôàéëà FIFO ñèñòåìà íå ñîçäàåò ñàì îáúåêò êàíàëà; ýòîïðîèñõîäèò òîëüêî òîãäà, êîãäà êàêîé-ëèáî ïðîöåññ îòêðûâàåò ôàéë FIFO ñïîìîùüþ âûçîâà open() íà ÷òåíèå èëè çàïèñü, ïðè÷åì îáúåêò êàíàëà ïðîäîëæàåò ñóùåñòâîâàòü äî òåõ ïîð, ïîêà ñóùåñòâóåò õîòÿ áû îäèí ñâÿçàííûéñ íèì äåñêðèïòîð, ïîñëå ÷åãî óíè÷òîæàåòñÿ.
Óíè÷òîæåíèå îáúåêòà êàíàëà íåîçíà÷àåò óíè÷òîæåíèÿ ôàéëà FIFO: ïîñëå çàêðûòèÿ âñåõ äåñêðèïòîðîâ ôàéëîñòàåòñÿ íà ìåñòå è ìîæåò áûòü ñíîâà îòêðûò êàêèì-ëèáî ïðîöåññîì, ïîñëå÷åãî îáúåêò êàíàëà ñíîâà ïîÿâèòñÿ.Ïðåæäå ÷åì íà÷àòü ïåðåäà÷ó äàííûõ, êàíàë íåîáõîäèìî îòêðûòü ñ îáîèõêîíöîâ. Îáû÷íî ïîïûòêà îòêðûòü êàíàë ñ îäíîé èç ñòîðîí áëîêèðóåòñÿ äîòåõ ïîð, ïîêà êòî-ëèáî íå îòêðîåò âòîðîé êîíåö êàíàëà.Ïîâåäåíèå èìåíîâàííîãî êàíàëà ïðè çàêðûòèè ïîñëåäíåãî èç äåñêðèïòîðîâ, îòâå÷àþùèõ çà îäèí èç êîíöîâ, ïîëíîñòüþ àíàëîãè÷íî ïîâåäåíèþ íåèìåíîâàííîãî êàíàëà â òàêèõ æå ñëó÷àÿõ, òî åñòü ïîïûòêà ÷èòàòü èç êàíàëà,ó êîòîðîãî çàêðûëñÿ ïîñëåäíèé ïèøóùèé äåñêðèïòîð, ïðèâîäèò ê ñèòóàöèèêîíåö ôàéëà, à ïîïûòêà ïèñàòü â êàíàë, ó êîòîðîãî çàêðûëñÿ ïîñëåäíèé ÷èòàþùèé äåñêðèïòîð, ïðèâîäèò ê ïîëó÷åíèþ ñèãíàëà SIGPIPE.
Ðàçíèöà çäåñüòîëüêî â òîì, ÷òî îáà ñëó÷àÿ íå ÿâëÿþòñÿ ôàòàëüíûìè; òàê, ïîñëå ïîëó÷åíèÿñèòóàöèè êîíåö ôàéëà, âîîáùå ãîâîðÿ, âîçìîæíî, ÷òî îäèí èç ñëåäóþùèõâûçîâîâ read() ïðî÷èòàåò ñ òîãî æå äåñêðèïòîðà êàêèå-òî äàííûå. Ýòî ïðîèçîéäåò, åñëè êàêîé-òî äðóãîé ïðîöåññ ñíîâà îòêðîåò òîò æå êàíàë íà çàïèñü.Ïðè ýòîì âñå âðåìÿ, ïîêà íè îäíîãî ïèøóùåãî äåñêðèïòîðà â ñèñòåìå íåò,read() áóäåò ïðîäîëæàòü âîçâðàùàòü 0 (ñèãíàëèçèðîâàòü î êîíöå ôàéëà).113Ëåêöèÿ 920Îòîáðàæåíèå ôàéëîâ â âèðòóàëüíîå àäðåñíîå ïðîñòðàíñòâî; ðàçäåëÿåìàÿ ïàìÿòü OC Unix ïðåäóñìîòðåíà âîçìîæíîñòü îòîáðàæåíèÿ ñîäåðæèìîãî íåêîòîðîãî ôàéëà â âèðòóàëüíîå àäðåñíîå ïðîñòðàíñòâî ïðîöåññà.
 ðåçóëüòàòåòàêîãî îòîáðàæåíèÿ ïîÿâëÿåòñÿ âîçìîæíîñòü ðàáîòû ñ äàííûìè â ôàéëå, êàêñ îáû÷íûìè ïåðåìåííûìè â îïåðàòèâíîé ïàìÿòè, òî åñòü, íàïðèìåð, ñ ïîìîùüþ ïðèñâàèâàíèé.Îòîáðàæåíèå îñóùåñòâëÿåòñÿ ñèñòåìíûì âûçîâîìvoid *mmap(void *start, int length, int protection,int flags, int fd, int offset);Ïåðåä âûçîâîì mmap() íåîáõîäèìî îòêðûòü ôàéë ñ ïîìîùüþ open(); âûçîâmmap() ïðèíèìàåò äåñêðèïòîð ôàéëà, ïîäëåæàùåãî îòîáðàæåíèþ, â êà÷åñòâåïàðàìåòðà fd. Ïàðàìåòðû offset è length çàäàþò, ñîîòâåòñòâåííî, ïîçèöèþíà÷àëà îòîáðàæàåìîãî ó÷àñòêà â ôàéëå è åãî äëèíó.
Çäåñü íåîáõîäèìî çàìåòèòü, ÷òî è äëèíà, è ïîçèöèÿ äîëæíû áûòü êðàòíû íåêîòîðîìó ïðåäîïðåäåëåííîìó ÷èñëó, íàçûâàåìîìó ðàçìåðîì ñòðàíèöû 1 . Åãî ìîæíî óçíàòü ñïîìîùüþ ôóíêöèèint getpagesize();Ïàðàìåòð protection âûçîâà mmap() çàäàåò ðåæèì äîñòóïà ê ïîëó÷àåìîìó ó÷àñòêó âèðòóàëüíîé ïàìÿòè. Äëÿ ýòîãî ñëóæàò êîíñòàíòû PROT_READ,PROT_WRITE è PROT_EXEC, êîòîðûå ìîæíî îáúåäèíÿòü îïåðàöèåé ïîáèòîâîãîèëè. Êàê ÿñíî èç íàçâàíèÿ, ïåðâûå äâå êîíñòàíòû ñîîòâåòñòâóþò äîñòóïó íà çàïèñü è ÷òåíèå. Òðåòüÿ ïîçâîëÿåò ïåðåäàâàòü óïðàâëåíèå â îáëàñòüîòîáðàæåíèÿ, òî åñòü èñïîëíÿòü òàì êîä; ýòî èñïîëüçóåòñÿ, íàïðèìåð, ïðèïîäãðóçêå äèíàìè÷åñêèõ áèáëèîòåê.
Ñóùåñòâóåò òàêæå êîíñòàíòà PROT_NONE,ñîîòâåòñòâóþùàÿ çàïðåòó äîñòóïà ëþáîãî âèäà.Çàäàâàåìûé ïàðàìåòðîì protection äîñòóï äîëæåí áûòü ñîâìåñòèì ñ ðåæèìîì, â êîòîðîì áûë îòêðûò ôàéë: òàê, åñëè ôàéë îòêðûò â ðåæèìå òîëüêî ÷òåíèå, òî åñòü â âûçîâå open() áûë èñïîëüçîâàí ôëàæîê O_RDONLY, òîïîïûòêà îòîáðàçèòü ôàéë â ïàìÿòü ñ ðåæèìîì, äîïóñêàþùèì çàïèñü, âûçîâåò îøèáêó.1 Çàìåòèì,ðàçìåð ñòðàíèöû äëÿ mmap() íå èìååò, âîîáùå ãîâîðÿ, ïðÿìîãî îòíîøåíèÿ ê ðàçìåðó ñòðàíèöû âèðòóàëüíîé ïàìÿòè114 êà÷åñòâå ïàðàìåòðà flags íåîáõîäèìî óêàçàòü ëèáî MAP_SHARED, ëèáîMAP_PRIVATE (â ýòîì ñëó÷àå èçìåíåíèÿ, ïðîèçâîäèìûå â âèðòóàëüíîì àäðåñíîì ïðîñòðàíñòâå, íèêàê íà ôàéëå íå îòðàçÿòñÿ).
Êðîìå òîãî, ê îäíîìó èçýòèõ äâóõ ôëàãîâ ìîæíî äîáàâèòü ÷åðåç îïåðàöèþ ïîáèòîâîãî èëè ôëàæêèäîïîëíèòåëüíûõ îïöèé. Ñðåäè ýòèõ îïöèé åñòü MAP_ANONYMOUS, ïîçâîëÿþùàÿñîçäàòü ïðîñòî îáëàñòü ðàçäåëÿåìîé ïàìÿòè (áåç ôàéëà); â ýòîì ñëó÷àå ïàðàìåòðû fd è offset èãíîðèðóþòñÿ.Ïàìÿòü, âûäåëåííàÿ ñ ïîìîùüþ mmap() ñ óêàçàíèåì MAP_ANONYMOUS, îòëè÷àåòñÿ îò îáû÷íîé òåì, ÷òî ïðè êîïèðîâàíèè ïðîöåññà âûçîâîì fork() îíàíå êîïèðóåòñÿ, à ñòàíîâèòñÿ äîñòóïíîé èç îáîèõ ïðîöåññîâ, òî åñòü èçìåíåíèÿ,ñäåëàííûå â òàêîé ïàìÿòè äî÷åðíèì ïðîöåññîì, áóäóò äîñòóïíû ðîäèòåëüñêîìó è íàîáîðîò.Ïàðàìåòð start ïîçâîëÿåò óêàçàòü ñèñòåìå, â êàêîì ìåñòå íàøåãî àäðåñíîãî ïðîñòðàíñòâà íàì õîòåëîñü áû âèäåòü íîâóþ îáëàñòü ïàìÿòè. Îáû÷íîïîëüçîâàòåëüñêèå ïðîãðàììû íå èñïîëüçóþò ýòó âîçìîæíîñòü; â êà÷åñòâå ïàðàìåòðà start ìîæíî ïåðåäàòü NULL, òîãäà ñèñòåìà ñàìà âûáåðåò ñâîáîäíóþîáëàñòü âèðíóàëüíîãî àäðåñíîãî ïðîñòðàíñòâà.Âûçîâ mmap() âîçâðàùàåò óêàçàòåëü íà ñîçäàííóþ îáëàñòü âèðòóàëüíîéïàìÿòè.
Îáû÷íî ýòîò óêàçàòåëü ïðåîáðàçóþò ê äðóãîìó òèïó, íàïðèìåð êchar*. ñëó÷àå îøèáêè mmap() âîçâðàùàåò çíà÷åíèå MAP_FAILED, ðàâíîå -1, ïðåîáðàçîâàííîé ê òèïó void*.Ïðèâåäåì ïðèìåð:int fd;char *ptr;fd = open("file.dat", O_RDWR);if(fd == -1) { /* ... îáðàáîòêà îøèáêè ... */ }ptr = (char*) mmap(NULL, 4096, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);if(ptr == MAP_FAILED) { /* ... îáðàáîòêà îøèáêè ... */ }Ïîñëå âûïîëíåíèÿ ýòèõ äåéñòâèé âûðàæåíèå ptr[25] áóäåò ðàâíî çíà÷åíèþ 26ãî áàéòà â ôàéëå "file.dat", ïðè÷åì îïåðàöèÿ ïðèñâàèâàíèÿptr[25] = 'a' çàíåñåò â ýòîò áàéò ñèìâîë 'a'.Ðàññìîòðèì äðóãîé ïðèìåð:int *ptr;ptr = (char*) mmap(NULL, 4096, PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS, 0, 0);if(ptr == MAP_FAILED) { /* ... îáðàáîòêà îøèáêè ...
*/ }115if(fork() == 0) {/* ... äî÷åðíèé ïðîöåññ ... */} else {/* ... ðîäèòåëüñêèé ïðîöåññ ... */} ýòîì ïðèìåðå ðîäèòåëüñêèé è äî÷åðíèé ïðîöåññû èìåþò äîñòóï ê îäíîìóè òîìó æå ìàññèâó öåëûõ ÷èñåë (äëèíîé 1024 ýëåìåíòà, åñëè ñ÷èòàòü, ÷òî intçàíèìàåò 4 áàéòà). Ìàññèâ äîñòóïåí ÷åðåç óêàçàòåëü ptr, òàê ÷òî åñëè îäèíèç ïðîöåññîâ ñäåëàåò ïðèñâàèâàíèå ptr[77] = 120, òî â îáîèõ ïðîöåññàõâûðàæåíèå ptr[77] áóäåò èìåòü çíà÷åíèå 120.Îòìåíèòü îòîáðàæåíèå, ñîçäàííîå âûçîâîì mmap(), ìîæíî ñ ïîìîùüþ âûçîâàint munmap(void *start, int lenght);Ôèçè÷åñêóþ çàïèñü â ôàéë èçìåíåíèé, ñäåëàííûõ â îáëàñòè îòîáðàæåíèÿ, ñèñòåìà ìîæåòïðîèçâåñòè íå ñðàçó.
Åñëè íåîáõîäèìî ãàðàíòèðîâàòü, ÷òî èçìåíåíèÿ ôèçè÷åñêè çàïèñàíû íàäèñê, ìîæíî âîñïîëüçîâàòüñÿ âûçîâîìmsync().Èçó÷åíèå ýòîãî âûçîâà îñòàâëÿåì ÷èòàòåëþäëÿ ñàìîñòîÿòåëüíîé ðàáîòû.21Âçàèìîäåéñòâèå ïðîöåññîâ ÷åðåç ïñåâäîòåðìèíàëÊàê óæå ãîâîðèëîñü, â ÎÑ Unix âàæíîå çíà÷åíèå èìååò ïîíÿòèå òåðìèíàëà.  íåêîòîðûõ ñëó÷àÿõ òåðìèíàë ïðèõîäèòñÿ ýìóëèðîâàòü ïðîãðàììíî −íàïðèìåð, â ñëó÷àå, åñëè ìû ïîëó÷àåì äîñòóï ê ìàøèíå óäàëåííî (ïî êîìïüþòåðíîé ñåòè), ëèáî ïðè çàïóñêå ïðîãðàììû xterm.