А.В. Столяров - Введение в операционные системы (1114673), страница 38
Текст из файла (страница 38)
Îòìåòèì, ÷òî â ðåàëèçàöèè ÎÑ Linux ýòà ôóíêöèÿ íå äåëàåò íè÷åãî, êðîìå ïðîâåðêè, íå íàõîäèòñÿ ëè êòî-ëèáî â ðåæèìå îæèäàíèÿ íà çàäàííîì ñåìàôîðå.29.5ÏðèìåðÐàññìîòðèì çàäà÷ó, â êîòîðîé íàì ïîòðåáóåòñÿ ðåàëèçîâàòü âçàèìîèñêëþ÷åíèå âèäà ïðîèçâîäèòåëè-ïîòðåáèòåëè.Ïóñòü äàíû íåñêîëüêî èñòî÷íèêîâ äàííûõ, èç êîòîðûõ ïîñòóïàþò â òåêñòîâîì âèäå ÷èñëà ñ ïëàâàþùåé òî÷êîé.  ðîëè èñòî÷íèêîâ ìîãóò âûñòóïàòü îáû÷íûå ôàéëû, à òàêæå ñîêåòû, FIFO èëè ñèìâîëüíî-îðèåíòèðîâàííûåóñòðîéñòâà, òî åñòü ïðî÷èòàòü ïîñëåäîâàòåëüíî ñíà÷àëà îäèí èñòî÷íèê, ïîòîìäðóãîé è ò.ï.
íåëüçÿ.Ïîëó÷àåìûå èç èñòî÷íèêîâ ÷èñëà íóæíî ïîäâåðãíóòü îïðåäåëåííîé îáðàáîòêå: âû÷èñëèòü äëÿ êàæäîãî ÷èñëà íàòóðàëüíûé ëîãàðèôì, à ðåçóëüòàòó÷åñòü òàêèì îáðàçîì, ÷òîáû â êàæäûé ìîìåíò âðåìåíè ìîæíî áûëî âûäàòü ñðåäíåå àðèôìåòè÷åñêîå âû÷èñëåííûõ çíà÷åíèé (äëÿ ýòîãî äîñòàòî÷íî,íàïðèìåð, õðàíèòü ñóììó âñåõ ðåçóëüòàòîâ è èõ îáùåå êîëè÷åñòâî).Âû÷èñëåíèå ëîãàðèôìîâ ñàìî ïî ñåáå ÿâëÿåòñÿ çàäà÷åé, òðåáóþùåé ïðîöåññîðíîãî âðåìåíè.
Äîïóñòèì, â íàøåé ñèñòåìå ìîæåò áûòü íåñêîëüêî ôèçè÷åñêèõ ïðîöåññîðîâ, òàê ÷òî ïðèìåíåíèå ïàðàëëåëüíûõ ïîòîêîâ ìîæåò óñêîðèòü îáðàáîòêó. Âìåñòå ñ òåì, íåèçâåñòíî, ñ êàêèìè ñêîðîñòÿìè áóäóò ïîñòóïàòü ÷èñëà îò èñòî÷íèêîâ, ïðè÷åì, âîçìîæíî, ýòè ñêîðîñòè îêàæóòñÿ ñóùåñòâåííûì îáðàçîì íåïîñòîÿííû.  ðåçóëüòàòå ïðîöåññîðû ìîãóò îêàçàòüñÿ÷àñòü âðåìåíè ïåðåãðóæåíû ðàáîòîé (÷òî ïðèâåäåò ê çàäåðæêàì â ïðèåìåäàííûõ îò èñòî÷íèêîâ), à ÷àñòü âðåìåíè − ïðîñòàèâàòü. ×òîáû ñãëàäèòü ýòèýôôåêòû, ìîæíî èñïîëüçîâàòü åäèíûé áóôåð äàííûõ äîñòàòî÷íîé âìåñòèìîñòè.Ðåàëèçóåì çàäà÷ó â ìíîãîïîòî÷íîé ñõåìå, âûäåëèâ ïî îäíîìó ïîòîêó íà÷òåíèå êàæäîãî èñòî÷íèêà äàííûõ è çàïóñòèì N ïîòîêîâ äëÿ îáðàáîòêè äàííûõ (ëîãàðèôìèðîâàíèÿ è ñóììèðîâàíèÿ).
Ïåðåäàâàòü äàííûå îò ïåðâûõ êïîñëåäíèì áóäåì ÷åðåç îáùèé áóôåð ïî ñõåìå ïðîèçâîäèòåëè-ïîòðåáèòåëè.Ïîñêîëüêó ñóììèðîâàíèå ïðèäåòñÿ âåñòè â îáùèõ ïåðåìåííûõ, äîñòóï êíèì íåîáõîäèìî îãðàíè÷èòü ìüþòåêñîì. ×òîáû óìåíüøèòü ïîòåðè íà îæèäàíèå ïîòîêàìè îñâîáîæäåíèÿ ýòîãî ìüþòåêñà, áóäåì íàêàïëèâàòü äàííûå âëîêàëüíûõ ïåðåìåííûõ ïîòîêà, à äîñòóï ê ãëîáàëüíîé ñóììå îñóùåñòâëÿòü ïî177íåáëîêèðóþùåìó ïðèíöèïó: åñëè çàõâàòèòü ìüþòåêñ óäàëîñü, ñáðàñûâàåì íàêîïëåííûå äàííûå, èíà÷å ðàáîòàåì äàëüøå, íàêàïëèâàÿ äàííûå â ëîêàëüíîìñóììàòîðå.Èìåíà ôàéëîâ èñòî÷íèêîâ ïîëó÷èì ñ êîìàíäíîé ñòðîêè.
×òîáû ðàáîòàòü ñïðîãðàììîé áûëî èíòåðåñíåå, ñäåëàåì òàê, ÷òîáû ãëàâíàÿ ïðîãðàììà êàæäûåïÿòü ñåêóíä âûäàâàëà çíà÷åíèå ñóììû è âû÷èñëåííîãî ñðåäíåãî, à ñ÷åò÷èêèîáíóëÿëà.Íàêîíåö, ïî ìåðå èñ÷åðïàíèÿ èñòî÷íèêîâ (ïî ïîëó÷åíèè êîíöà ôàéëà)áóäåì çàâåðøàòü ïîòîêè-ïðîèçâîäèòåëè. ßñíî, ÷òî ïî çàâåðøåíèè ïîñëåäíåãî ïðîèçâîäèòåëÿ äàëüíåéøàÿ ðàáîòà ïðîãðàììû òåðÿåò ñìûñë. Ñîîòâåòñòâåííî, ïðåäóñìîòðèì ìåõàíèçì ïîäñ÷åòà îñòàâøèõñÿ ïðîèçâîäèòåëåé.×òîáû íå âîçèòüñÿ ñ ìüþòåêñîì è ãëîáàëüíîé ïåðåìåííîé, âîñïîëüçóåìñÿîáûêíîâåííûì ñåìàôîðîì; â ýòîì ñëó÷àå áóäåì èñïîëüçîâàòü ñåìàôîð èñêëþ÷èòåëüíî ðàäè àòîìàðíîñòè äåéñòâèé íàä íèì, áåç áëîêèðîâîê.Ïîëíîñòüþ ïðîãðàììà ïðèâåäåíà â ëèñòèíãå íà ñòð.
179−181.×òîáû îïðîáîâàòü ïðîãðàììó, ñîçäàéòå íåñêîëüêî èìåíîâàííûõ êàíàëîâñ ïîìîùüþ êîìàíäû mkfifo. Çàïóñòèâ íåñêîëüêî ïðîãðàìì xterm, ñîçäàéòå ïðîöåññû, ÷èòàþùèå ñ êëàâèàòóðû è ïèøóùèå â òîëüêî ÷òî ñîçäàííûåèìåíîâàííûå êàíàëû. Ýòî ïðîùå âñåãî ñäåëàòü ñ ïîìîùüþ êîìàíäû cat è ïåðåíàïðàâëåíèÿ âûâîäà.
 îòäåëüíîì îêíå çàïóñòèòå íàøó ïðîãðàììó, óêàçàâåé èìåíà âàøèõ êàíàëîâ â êîìàíäíîé ñòðîêå. Òåïåðü ìîæíî ââîäèòü ÷èñëàíà âõîä ïðîãðàììàì cat; íàøà ïðîãðàììà áóäåò èõ îáðàáàòûâàòü.178#include#include#include#include#include<stdio.h><unistd.h><pthread.h><semaphore.h><math.h>#define BUFFER_SIZE 4096/* Áóôåð îáìåíà ìåæäó ïðîèçâîäèòåëÿìè è ïîòðåáèòåëÿìè */struct buf_str {int count;double values[BUFFER_SIZE];} buffer;void init_buffer(){buffer.count = 0;}void put_buffer_item(double v){buffer.values[buffer.count] = v;buffer.count++;}double get_buffer_item(){buffer.count--;return buffer.values[buffer.count];}/* ñåìàôîðû è ìüþòåêñ äëÿ îðãàíèçàöèè ðàáîòû ñ áóôåðîì */sem_t buf_empty;sem_t buf_full;pthread_mutex_t buf_mutex = PTHREAD_MUTEX_INITIALIZER;/* ïåðåìåííûå äëÿ ñóììèðîâàíèÿ è ìüþòåêñ äëÿ èõ çàùèòû */double grand_total = 0;long grand_count = 0;pthread_mutex_t grand_mutex = PTHREAD_MUTEX_INITIALIZER;/* ñåìàôîð äëÿ ïîäñ÷åòà îñòàâøèõñÿ "ïðîèçâîäèòåëåé" */sem_t producers_count;179/* Ïîòîê äëÿ ÷òåíèÿ äàííûõ ("ïðîèçâîäèòåëü") */void *producer_thread(void *v){/* ïîëó÷àåì â v óêàçàòåëü íà èìÿ èñòî÷íèêà */double val;FILE *f = fopen((char*)v, "r");if(!f) return NULL;sem_post(&producers_count);while(!feof(f)) {if(1 != fscanf(f, "%lf", &val)) continue;sem_wait(&buf_empty);/* àëãîðèòì ïðîèçâîäèòåëÿ */pthread_mutex_lock(&buf_mutex);put_buffer_item(val);pthread_mutex_unlock(&buf_mutex);sem_post(&buf_full);/*------*/}sem_trywait(&producers_count);return NULL;}/* Ïîòîê-ïîòðåáèòåëü.
Ïîëó÷àåìîå âõîäíîå çíà÷åíèå èãíîðèðóåò */void *consumer_thread(void *ignored){double local_total = 0; /* ëîêàëüíûå ñóììàòîðû */long local_count = 0;for(;;) {double val;sem_wait(&buf_full);/* àëãîðèòì ïîòðåáèòåëÿ */pthread_mutex_lock(&buf_mutex);val = get_buffer_item();pthread_mutex_unlock(&buf_mutex);sem_post(&buf_empty);/*------*//* òåïåðü ìîæíî çàíÿòüñÿ âû÷èñëåíèÿìè */local_total += log(val); local_count++;/* åñëè åñòü âîçìîæíîñòü, ñáðàñûâàåì äàííûå */if(0==pthread_mutex_trylock(&grand_mutex)) {grand_total += local_total;grand_count += local_count;local_total = 0; local_count = 0;pthread_mutex_unlock(&grand_mutex);}}}180int main(int argc, char **argv){pthread_t thr;int i;/* èíèöèàëèçèðóåì ãëîáàëüíûå äàííûå */init_buffer();sem_init(&buf_empty, 0, BUFFER_SIZE);sem_init(&buf_full, 0, 0);sem_init(&producers_count, 0, 0);/* çàïóñêàåì "ïðîèçâîäèòåëåé" */for(i = 1; i<argc; i++)pthread_create(&thr, NULL, producer_thread, (void*)argv[i]);/* çàïóñêàåì "ïîòðåáèòåëåé" */for(i = 0; i<10; i++)pthread_create(&thr, NULL, consumer_thread, NULL);}/* òåïåðü êàæäûå 5 ñåêóíä ïå÷àòàåì è îáíóëÿåì ðåçóëüòàò */for(;;) {int p_c;sleep(5);pthread_mutex_lock(&grand_mutex);/* âî èçáåæàíèå äåëåíèÿ íà 0 ïðîâåðèì íàëè÷èå äàííûõ */if(grand_count>0) {printf("total average: %f (sum = %f; count = %ld)\n",grand_total/((double)grand_count),grand_total, grand_count);} else {printf("No data yet...\n");}grand_total = 0; grand_count = 0;pthread_mutex_unlock(&grand_mutex);sem_getvalue(&producers_count, &p_c);if(p_c == 0) {printf("No more producers\n");break;}}return 0;181Ëåêöèÿ 1530Ãðàôè÷åñêèé èíòåðôåéñ â ÎÑ Unix.
Ñèñòåìà X WindowÐàíåå ìû óæå óïîìèíàëè òîò ôàêò, ÷òî ÎÑ Unix êàê òàêîâàÿ íå ïðåòåðïåëà ñóùåñòâåííûõ àðõèòåêòóðíûõ èçìåíåíèé äàæå ïðè òàêîì ñåðüåçíîì øàãå,êàê ââåäåíèå ãðàôè÷åñêèõ îáîëî÷åê. Äàâàéòå ïîïðîáóåì ðàçîáðàòüñÿ, êàê ýòîñòàëî âîçìîæíûì.30.1Áàçîâûå ïðèíöèïû ïîñòðîåíèÿ X WindowÑðåäñòâà, èñïîëüçóåìûå â ÎÑ Unix äëÿ ðàáîòû ñ ãðàôè÷åñêèìè (îêîííûìè) ïðèëîæåíèÿìè, ïîëó÷èëè îáùåå íàçâàíèå X Window System. Èíîãäàìîæíî âñòðåòèòü â ëèòåðàòóðå è ðàçãîâîðàõ íàèìåíîâàíèå XWindows.
Òàêîå íàèìåíîâàíèå ÿâëÿåòñÿ êàòåãîðè÷åñêè íåïðàâèëüíûì, ÷òî ñîçäàòåëè ñèñòåìû X Window íàñòîé÷èâî ïîä÷åðêèâàþò. Ñëîâî window (îêíî) â íàèìåíîâàíèè ýòîé ñèñòåìû äîëæíî ñòîÿòü â åäèíñòâåííîì ÷èñëå.Ïðåæäå âñåãî íåîáõîäèìî îòìåòèòü, ÷òî ïðèëîæåíèå, èñïîëüçóþùåå îêîííûé ãðàôè÷åñêèé èíòåðôåéñ, ïðîäîëæàåò ïðè ýòîì áûòü îáû÷íûì Unixïðîöåññîì.  ÷àñòíîñòè, êàê è ó ëþáîãî Unix-ïðîöåññà, ó îêîííîãî ïðèëîæåíèÿ åñòü ïàðàìåòðû êîìàíäíîé ñòðîêè, à òàêæå äåñêðèïòîðû ñòàíäàðòíîãîââîäà, âûâîäà è ñîîáùåíèé îá îøèáêàõ (stdin, stdout, stderr).×òîáû îòîáðàçèòü îêíî, ïðèëîæåíèå äîëæíî óñòàíîâèòü ñîåäèíåíèå ñ ñèñòåìîé X Window è îòïðàâèòü çàïðîñ â ñîîòâåòñòâèè ñ îïðåäåëåííûìè ñîãëàøåíèÿìè, èçâåñòíûìè êàê X-ïðîòîêîë.Ïî òó ñòîðîíó ñîåäèíåíèÿ íàõîäèòñÿ ïðîãðàììà, íàçûâàåìàÿ Xñåðâåðîì. Èìåííî ýòà ïðîãðàììà ïðîèçâîäèò íåïîñðåäñòâåííîå îòîáðàæåíèåãðàôè÷åñêèõ îáúåêòîâ íà ýêðàíå ïîëüçîâàòåëÿ. Ïî ñîáñòâåííîé èíèöèàòèâåýòà ïðîãðàììà íè÷åãî íå ðèñóåò; ÷òîáû íà ýêðàíå ÷òî-òî ïîÿâèëîñü, íåîáõîäèìçàïðîñ îò êàêîé-ëèáî ïðîãðàììû íà îòðèñîâêó òîãî èëè èíîãî èçîáðàæåíèÿ.Òàêèì îáðàçîì, â îñíîâíîì îòîáðàæàþùàÿ ïðîãðàììà âûïîëíÿåò äåéñòâèÿâ îòâåò íà çàïðîñû äðóãèõ ïðîãðàìì (êëèåíòîâ), ÷òî îïðàâäûâàåò íàçâàíèåX-ñåðâåð.
Óñëóãîé (ñåðâèñîì), êîòîðóþ îêàçûâàåò êëèåíòàì ýòîò ñåðâåð,ÿâëÿåòñÿ îòðèñîâêà èçîáðàæåíèé íà ýêðàíå.Ñëåäóåò, ïðàâäà, çàìåòèòü, ÷òî X-ñåðâåð â íåêîòîðûõ ñëó÷àÿõ ñàì ïðîÿâëÿåò èíèöèàòèâó ïðè îáùåíèè ñ êëèåíòîì. Ýòî ïðîèñõîäèò ïðè âîçíèêíîâåíèè òåõ èëè èíûõ ñîáûòèé, îòíîñÿùèõñÿ ê îáëàñòè ýêðàíà, â êîòîðîé îòîáðàæåíî îêíî êëèåíòà; ê òàêèì ñîáûòèÿì îòíîñÿòñÿ, íàïðèìåð, íàæàòèÿ ïîëü182çîâàòåëåì êëàâèø íà êëàâèàòóðå, äâèæåíèÿ è ùåë÷êè ìûøè, ïåðåìåùåíèÿîêîí, òðåáóþùèå ïîëíîé èëè ÷àñòè÷íîé ïîâòîðíîé îòðèñîâêè èçîáðàæåíèÿ âîêíå, è ò.ä.Ñîåäèíåíèå ñ X-ñåðâåðîì îñóùåñòâëÿåòñÿ ÷åðåç ïîòîêîâûé ñîêåò (ñîêåòòèïà SOCK_STREAM), ïðè÷åì îáû÷íî X-ñåðâåð çàâîäèò ñëóøàþùèå ñîêåòû êàêâ ñåìåéñòâå AF_UNIX, òàê è â ñåìåéñòâå AF_INET, ÷òî ïîçâîëÿåò ñâÿçûâàòüñÿñ X-ñåðâåðîì ïî ñåòè. Òàêèì îáðàçîì, ïðè ðàáîòå ñ X Window âîçìîæíî çàïóñêàòü îêîííûå ïðèëîæåíèÿ íà óäàëåííûõ êîìïüþòåðàõ, ïðè ýòîì èõ îêíàâèäåòü ëîêàëüíî.Âàæíî îòìåòèòü, ÷òî X-ñåðâåð òàêæå ÿâëÿåòñÿ îáûêíîâåííûì ïðîöåññîì,îáû÷íî, ïðàâäà, èìåþùèì îïðåäåëåííûå ïðèâèëåãèè äëÿ äîñòóïà ê ñîîòâåòñòâóþùåìó îáîðóäîâàíèþ.