Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00380 008670 10462835 na godz. na dobę w sumie
Linux. Programowanie systemowe. Wydanie II - książka
Linux. Programowanie systemowe. Wydanie II - książka
Autor: Liczba stron: 448
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-8285-0 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> systemy operacyjne >> linux
Porównaj ceny (książka, ebook, audiobook).

Przewodnik po jądrze sytemu Linux!

Jądro systemu Linux to jeden z największych projektów rozwijanych przez ogromną społeczność. Setki wolontariuszy dniami i nocami rozwijają najważniejszy element tego systemu operacyjnego. I robią to naprawdę skutecznie! Każde kolejne wydanie Linuksa zawiera dziesiątki nowinek oraz ulepszeń - jest coraz szybsze, bezpieczniejsze i po prostu lepsze. Jednak początkujący programiści mogą mieć problemy z wykorzystaniem usług dostarczanych przez kernel. Masz obawy, że nie odnajdziesz się w gąszczu możliwości współczesnego jądra systemu Linux?

Ta książka rozwieje je w mig. Jest to wyjątkowa pozycja na rynku wydawniczym, zgłębiająca właśnie te tajemnice. W trakcie lektury nauczysz się tworzyć niskopoziomowe oprogramowanie, które będzie się komunikowało bezpośrednio z jądrem systemu. Operacje wejścia i wyjścia, strumienie, zdarzenia, procesy to tylko część elementów, które błyskawicznie opanujesz. Ponadto nauczysz się zarządzać katalogami i plikami oraz poznasz koncepcję sygnałów. Książka ta jest niezastąpionym źródłem informacji dla wszystkich programistów pracujących z jądrem Linuksa. Docenisz tę lekturę!

Poznaj:

Poznaj jądro systemu od podszewki!

 


 

Robert Love - od wielu lat jest użytkownikiem i współtwórcą systemu Linux. Rozwija środowisko graficzne GNOME oraz jądro systemu. Pracuje jako projektant oprogramowania w firmie Google, był też członkiem zespołu projektującego system operacyjny Android. Jest autorem licznych książek poświęconych programowaniu w systemie Linux.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Linux System Programming: Talking Directly to the Kernel and C Library, 2nd Edition Tłumaczenie: Jacek Janusz ISBN: 978-83-246-8285-0 © 2014 Helion S.A. Authorized Polish translation of the English edition Linux System Programming, 2nd Edition, ISBN 9781449339531 © 2013 Robert Love. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyło wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie bierze jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Wydawnictwo HELION nie ponosi również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/linps2 Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis tre(cid:316)ci Przedmowa .................................................................................................................. 13 Wst(cid:253)p ........................................................................................................................... 15 Programowanie systemowe API i ABI API ABI Standardy Dlaczego warto uczy(cid:232) si(cid:246) programowania systemowego? Kamienie w(cid:246)gielne programowania systemowego Funkcje systemowe Biblioteka j(cid:246)zyka C Kompilator j(cid:246)zyka C 1. Wprowadzenie — podstawowe poj(cid:253)cia .................................................................... 21 21 22 23 23 24 24 25 25 26 27 27 28 28 29 29 30 36 38 39 39 40 40 40 43 Pliki i system plików Procesy U(cid:276)ytkownicy i grupy Uprawnienia Sygna(cid:228)y Komunikacja mi(cid:246)dzyprocesowa Pliki nag(cid:228)ówkowe Obs(cid:228)uga b(cid:228)(cid:246)dów Historia POSIX oraz SUS Standardy j(cid:246)zyka C Linux i standardy Ksi(cid:241)(cid:276)ka i standardy Poj(cid:246)cia dotycz(cid:241)ce programowania w Linuksie Pocz(cid:241)tek programowania systemowego 3 Kup książkęPoleć książkę Zsynchronizowane operacje wej(cid:264)cia i wyj(cid:264)cia Funkcja systemowa open() W(cid:228)a(cid:264)ciciele nowych plików Uprawnienia nowych plików Funkcja creat() Warto(cid:264)ci zwracane i kody b(cid:228)(cid:246)dów Warto(cid:264)ci zwracane Czytanie wszystkich bajtów Odczyty nieblokuj(cid:241)ce Inne warto(cid:264)ci b(cid:228)(cid:246)dów Ograniczenia rozmiaru dla funkcji read() Zapisy cz(cid:246)(cid:264)ciowe Tryb dopisywania Zapisy nieblokuj(cid:241)ce Inne kody b(cid:228)(cid:246)dów Ograniczenia rozmiaru dla funkcji write() Sposób dzia(cid:228)ania funkcji write() 2. Plikowe operacje wej(cid:316)cia i wyj(cid:316)cia .............................................................................45 46 46 49 49 51 52 52 53 54 55 55 56 56 57 57 58 58 59 59 60 60 62 63 63 64 65 65 66 67 67 68 68 69 69 70 71 76 80 81 81 82 84 85 Szukanie za pomoc(cid:241) funkcji lseek() Szukanie poza ko(cid:254)cem pliku Kody b(cid:228)(cid:246)dów Ograniczenia Odczyty i zapisy pozycyjne Funkcja select() Funkcja poll() Porównanie funkcji poll() i select() Organizacja wewn(cid:246)trzna j(cid:241)dra Funkcje fsync() i fdatasync() Funkcja sync() Znacznik O_SYNC Znaczniki O_DSYNC i O_RSYNC Bezpo(cid:264)rednie operacje wej(cid:264)cia i wyj(cid:264)cia Zamykanie plików Kody b(cid:228)(cid:246)dów Obcinanie plików Zwielokrotnione operacje wej(cid:264)cia i wyj(cid:264)cia Kody b(cid:228)(cid:246)dów Otwieranie plików Czytanie z pliku przy u(cid:276)yciu funkcji read() Pisanie za pomoc(cid:241) funkcji write() Wirtualny system plików Bufor stron Opó(cid:274)niony zapis stron Zako(cid:254)czenie 4 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę Wska(cid:274)niki do plików Otwieranie plików Tryby Pisanie do strumienia Otrzymywanie informacji o aktualnym po(cid:228)o(cid:276)eniu w strumieniu Operacje wej(cid:264)cia i wyj(cid:264)cia buforowane w przestrzeni u(cid:276)ytkownika Rozmiar bloku Typowe operacje wej(cid:264)cia i wyj(cid:264)cia Zamykanie wszystkich strumieni Czytanie ze strumienia Czytanie pojedynczego znaku Czytanie ca(cid:228)ego wiersza Czytanie danych binarnych Otwieranie strumienia poprzez deskryptor pliku Zamykanie strumieni 3. Buforowane operacje wej(cid:316)cia i wyj(cid:316)cia ......................................................................87 87 89 90 90 91 91 92 93 93 93 93 94 96 97 97 98 98 99 100 101 102 102 103 104 105 106 107 108 109 Opró(cid:276)nianie strumienia B(cid:228)(cid:246)dy i koniec pliku Otrzymywanie skojarzonego deskryptora pliku Parametry buforowania Bezpiecze(cid:254)stwo w(cid:241)tków Przyk(cid:228)adowy program u(cid:276)ywaj(cid:241)cy buforowanych operacji wej(cid:264)cia i wyj(cid:264)cia Szukanie w strumieniu Krytyczna analiza biblioteki typowych operacji wej(cid:264)cia i wyj(cid:264)cia Zako(cid:254)czenie Zapisywanie pojedynczego znaku Zapisywanie (cid:228)a(cid:254)cucha znaków Zapisywanie danych binarnych Nieautomatyczne blokowanie plików Nieblokowane operacje na strumieniu Odpytywanie zdarze(cid:254) Funkcje readv() i writev() Rozproszone operacje wej(cid:264)cia i wyj(cid:264)cia 4. Zaawansowane operacje plikowe wej(cid:316)cia i wyj(cid:316)cia ................................................. 111 112 112 117 117 118 121 122 123 123 128 Tworzenie nowego egzemplarza interfejsu odpytywania zdarze(cid:254) Sterowanie dzia(cid:228)aniem interfejsu odpytywania zdarze(cid:254) Oczekiwanie na zdarzenie w interfejsie odpytywania zdarze(cid:254) Zdarzenia prze(cid:228)(cid:241)czane zboczem a zdarzenia prze(cid:228)(cid:241)czane poziomem Funkcja mmap() Funkcja munmap() Odwzorowywanie plików w pami(cid:246)ci Spis tre(cid:316)ci (cid:95) 5 Kup książkęPoleć książkę Przyk(cid:228)ad odwzorowania w pami(cid:246)ci Zalety u(cid:276)ywania funkcji mmap() Wady u(cid:276)ywania funkcji mmap() Zmiana rozmiaru odwzorowania Zmiana uprawnie(cid:254) odwzorowania Synchronizacja odwzorowanego pliku Dostarczanie porad dotycz(cid:241)cych odwzorowania w pami(cid:246)ci Porady dla standardowych operacji plikowych wej(cid:264)cia i wyj(cid:264)cia Funkcja systemowa posix_fadvise() Funkcja systemowa readahead() Porada jest tania Operacje zsynchronizowane, synchroniczne i asynchroniczne Asynchroniczne operacje wej(cid:264)cia i wyj(cid:264)cia Zarz(cid:241)dcy operacji wej(cid:264)cia i wyj(cid:264)cia oraz wydajno(cid:264)(cid:232) operacji wej(cid:264)cia i wyj(cid:264)cia Adresowanie dysku Dzia(cid:228)anie zarz(cid:241)dcy operacji wej(cid:264)cia i wyj(cid:264)cia Wspomaganie odczytów Wybór i konfiguracja zarz(cid:241)dcy operacji wej(cid:264)cia i wyj(cid:264)cia Optymalizowanie wydajno(cid:264)ci operacji wej(cid:264)cia i wyj(cid:264)cia Zako(cid:254)czenie 128 130 130 131 132 133 134 137 137 138 139 140 141 142 142 143 143 147 148 154 Programy, procesy i w(cid:241)tki Identyfikator procesu 5. Zarz(cid:233)dzanie procesami ............................................................................................. 155 155 156 156 157 157 Przydzia(cid:228) identyfikatorów procesów Hierarchia procesów Typ pid_t Otrzymywanie identyfikatora procesu oraz identyfikatora procesu rodzicielskiego Uruchamianie nowego procesu Rodzina funkcji exec Funkcja systemowa fork() Zako(cid:254)czenie procesu Inne sposoby na zako(cid:254)czenie procesu Funkcja atexit() Funkcja on_exit() Sygna(cid:228) SIGCHLD Oczekiwanie na zako(cid:254)czone procesy potomka Oczekiwanie na okre(cid:264)lony proces Jeszcze wszechstronniejsza funkcja oczekiwania BSD wkracza do akcji: funkcje wait3() i wait4() Uruchamianie i oczekiwanie na nowy proces Procesy zombie 6 (cid:95) Spis tre(cid:316)ci 158 158 158 162 166 167 167 168 169 169 171 173 175 177 179 Kup książkęPoleć książkę U(cid:276)ytkownicy i grupy Rzeczywiste, efektywne oraz zapisane identyfikatory u(cid:276)ytkownika i grupy Zmiana rzeczywistego lub zapisanego identyfikatora dla u(cid:276)ytkownika lub grupy Zmiana efektywnego identyfikatora dla u(cid:276)ytkownika lub grupy Zmiana identyfikatora dla u(cid:276)ytkownika lub grupy w wersji BSD Zmiana identyfikatora dla u(cid:276)ytkownika lub grupy w wersji HP-UX Zalecane modyfikacje identyfikatorów u(cid:276)ytkownika i grupy Wsparcie dla zapisanych identyfikatorów u(cid:276)ytkownika Otrzymywanie identyfikatorów u(cid:276)ytkownika i grupy Grupy sesji i procesów Funkcje systemowe do obs(cid:228)ugi sesji Funkcje systemowe do obs(cid:228)ugi grup procesów Przestarza(cid:228)e funkcje do obs(cid:228)ugi grupy procesów Demony Zako(cid:254)czenie 179 180 181 182 182 183 183 184 184 184 186 187 188 189 191 Completely Fair Scheduler Udost(cid:246)pnianie czasu procesora Prawid(cid:228)owe sposoby u(cid:276)ycia sched_yield() Systemy czasu rzeczywistego Priorytety procesu nice() getpriority() i setpriority() Priorytety wej(cid:264)cia i wyj(cid:264)cia Szeregowanie procesów Przedzia(cid:228)y czasowe Procesy zwi(cid:241)zane z wej(cid:264)ciem i wyj(cid:264)ciem a procesy zwi(cid:241)zane z procesorem Szeregowanie z wyw(cid:228)aszczaniem 6. Zaawansowane zarz(cid:233)dzanie procesami .................................................................. 193 193 194 194 195 196 197 198 199 199 200 201 202 203 205 205 206 207 208 211 214 215 216 218 220 223 Systemy (cid:264)cis(cid:228)ego oraz zwyk(cid:228)ego czasu rzeczywistego Opó(cid:274)nienie, rozsynchronizowanie oraz parametry graniczne Obs(cid:228)uga czasu rzeczywistego przez system Linux Linuksowe strategie szeregowania i ustalania priorytetów Ustawianie parametrów szeregowania sched_rr_get_interval() (cid:263)rodki ostro(cid:276)no(cid:264)ci przy pracy z procesami czasu rzeczywistego Determinizm Wi(cid:241)zanie procesów do konkretnego procesora sched_getaffinity() i sched_setaffinity() Ograniczenia zasobów systemowych Ograniczenia Ustawianie i odczytywanie ogranicze(cid:254) Spis tre(cid:316)ci (cid:95) 7 Kup książkęPoleć książkę Modele w(cid:241)tkowo(cid:264)ci Wzorce w(cid:241)tkowo(cid:264)ci Binaria, procesy i w(cid:241)tki Wielow(cid:241)tkowo(cid:264)(cid:232) Koszty wielow(cid:241)tkowo(cid:264)ci Alternatywy dla wielow(cid:241)tkowo(cid:264)ci W(cid:241)tkowo(cid:264)(cid:232) na poziomie u(cid:276)ytkownika W(cid:241)tkowo(cid:264)(cid:232) mieszana Wspó(cid:228)programy i w(cid:228)ókna W(cid:241)tkowo(cid:264)(cid:232) thread-per-connection W(cid:241)tkowo(cid:264)(cid:232) sterowana zdarzeniami Wspó(cid:228)bie(cid:276)no(cid:264)(cid:232), równoleg(cid:228)o(cid:264)(cid:232) i wy(cid:264)cigi 7. W(cid:233)tkowo(cid:316)(cid:235) ................................................................................................................225 225 226 228 228 229 229 230 230 231 231 232 233 233 236 236 238 239 240 240 241 241 243 243 246 247 248 251 Implementacje w(cid:241)tkowo(cid:264)ci w Linuksie Interfejs programistyczny dla standardu Pthreads Konsolidowanie implementacji Pthreads Tworzenie w(cid:241)tków Identyfikatory w(cid:241)tków Ko(cid:254)czenie w(cid:241)tków (cid:227)(cid:241)czenie i od(cid:228)(cid:241)czanie w(cid:241)tków Przyk(cid:228)ad w(cid:241)tkowo(cid:264)ci Muteksy standardu Pthreads Dalsze zdobywanie wiedzy Sytuacje wy(cid:264)cigów Synchronizacja Muteksy Zakleszczenia Standard Pthreads Pliki i ich metadane Rodzina funkcji stat Uprawnienia Prawa w(cid:228)asno(cid:264)ci Atrybuty rozszerzone Operacje dla atrybutów rozszerzonych 8. Zarz(cid:233)dzanie plikami i katalogami ............................................................................253 253 253 257 259 261 264 269 270 275 276 278 Aktualny katalog roboczy Tworzenie katalogów Usuwanie katalogów Odczytywanie zawarto(cid:264)ci katalogu Katalogi 8 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę Dowi(cid:241)zania Dowi(cid:241)zania twarde Dowi(cid:241)zania symboliczne Usuwanie elementów z systemu plików Kopiowanie i przenoszenie plików Kopiowanie Przenoszenie W(cid:246)z(cid:228)y urz(cid:241)dze(cid:254) Specjalne w(cid:246)z(cid:228)y urz(cid:241)dze(cid:254) Generator liczb losowych Komunikacja poza kolejk(cid:241) (cid:263)ledzenie zdarze(cid:254) zwi(cid:241)zanych z plikami Inicjalizacja interfejsu inotify Elementy obserwowane Zdarzenia interfejsu inotify Zaawansowane opcje obserwowania Usuwanie elementu obserwowanego z interfejsu inotify Otrzymywanie rozmiaru kolejki zdarze(cid:254) Usuwanie egzemplarza interfejsu inotify 280 281 282 284 286 286 286 288 289 289 290 292 292 293 295 298 299 300 300 Przestrze(cid:254) adresowa procesu Strony i stronicowanie Regiony pami(cid:246)ci Przydzielanie pami(cid:246)ci dynamicznej Przydzielanie pami(cid:246)ci dla tablic Zmiana wielko(cid:264)ci obszaru przydzielonej pami(cid:246)ci Zwalnianie pami(cid:246)ci dynamicznej Wyrównanie 9. Zarz(cid:233)dzanie pami(cid:253)ci(cid:233) ............................................................................................... 301 301 301 303 304 306 307 309 310 315 315 317 318 319 Tworzenie anonimowych odwzorowa(cid:254) w pami(cid:246)ci Odwzorowanie pliku /dev/zero Zarz(cid:241)dzanie segmentem danych Anonimowe odwzorowania w pami(cid:246)ci Zaawansowane operacje przydzia(cid:228)u pami(cid:246)ci Dok(cid:228)adne dostrajanie przy u(cid:276)yciu funkcji malloc_usable_size() oraz malloc_trim() Uruchamianie programów u(cid:276)ywaj(cid:241)cych systemu przydzielania pami(cid:246)ci Otrzymywanie danych statystycznych Przydzia(cid:228)y pami(cid:246)ci wykorzystuj(cid:241)ce stos Powielanie (cid:228)a(cid:254)cuchów znakowych na stosie Tablice o zmiennej d(cid:228)ugo(cid:264)ci Wybór mechanizmu przydzielania pami(cid:246)ci 322 323 323 324 326 326 327 Spis tre(cid:316)ci (cid:95) 9 Kup książkęPoleć książkę Operacje na pami(cid:246)ci Ustawianie warto(cid:264)ci bajtów Porównywanie bajtów Przenoszenie bajtów Wyszukiwanie bajtów Manipulowanie bajtami Blokowanie pami(cid:246)ci Blokowanie fragmentu przestrzeni adresowej Blokowanie ca(cid:228)ej przestrzeni adresowej Odblokowywanie pami(cid:246)ci Ograniczenia blokowania Czy strona znajduje si(cid:246) w pami(cid:246)ci fizycznej? Przydzia(cid:228) oportunistyczny Przekroczenie zakresu zatwierdzenia oraz stan braku pami(cid:246)ci (OOM) 328 329 329 330 331 332 332 333 334 335 335 336 336 337 Koncepcja sygna(cid:228)ów Wysy(cid:228)anie sygna(cid:228)u Identyfikatory sygna(cid:228)ów Sygna(cid:228)y wspierane przez system Linux Uprawnienia Przyk(cid:228)ady Wysy(cid:228)anie sygna(cid:228)u do samego siebie Wysy(cid:228)anie sygna(cid:228)u do ca(cid:228)ej grupy procesów Podstawowe zarz(cid:241)dzanie sygna(cid:228)ami Oczekiwanie na dowolny sygna(cid:228) Przyk(cid:228)ady Uruchomienie i dziedziczenie Odwzorowanie numerów sygna(cid:228)ów na (cid:228)a(cid:254)cuchy znakowe 10. Sygna(cid:293)y .......................................................................................................................339 340 340 341 346 347 348 349 350 351 352 352 353 353 354 354 356 356 357 358 358 359 361 363 366 367 367 Odzyskiwanie oczekuj(cid:241)cych sygna(cid:228)ów Oczekiwanie na zbiór sygna(cid:228)ów Zaawansowane zarz(cid:241)dzanie sygna(cid:228)ami Wysy(cid:228)anie sygna(cid:228)u z wykorzystaniem pola u(cid:276)ytkowego Przyk(cid:228)ad wykorzystania pola u(cid:276)ytkowego Inne funkcje obs(cid:228)uguj(cid:241)ce zbiory sygna(cid:228)ów Blokowanie sygna(cid:228)ów Wspó(cid:228)u(cid:276)ywalno(cid:264)(cid:232) Zbiory sygna(cid:228)ów Funkcje, dla których wspó(cid:228)u(cid:276)ywalno(cid:264)(cid:232) jest zagwarantowana Struktura siginfo_t Wspania(cid:228)y (cid:264)wiat pola si_code U(cid:228)omno(cid:264)(cid:232) systemu Unix? 10 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę Struktury danych reprezentuj(cid:241)ce czas Zegary POSIX Rozdzielczo(cid:264)(cid:232) (cid:274)ród(cid:228)a czasu Pobieranie aktualnego czasu Lepszy interfejs Interfejs zaawansowany Pobieranie czasu procesu Ustawianie aktualnego czasu Reprezentacja pierwotna Nast(cid:246)pna wersja — dok(cid:228)adno(cid:264)(cid:232) na poziomie mikrosekund Kolejna, lepsza wersja — dok(cid:228)adno(cid:264)(cid:232) na poziomie nanosekund Wy(cid:228)uskiwanie sk(cid:228)adników czasu Typ danych dla czasu procesu 11. Czas ............................................................................................................................369 371 372 372 372 373 374 374 375 376 377 377 378 379 379 380 381 382 385 386 387 389 390 391 391 392 392 392 394 Obs(cid:228)uga stanu u(cid:264)pienia z dok(cid:228)adno(cid:264)ci(cid:241) do mikrosekund Obs(cid:228)uga stanu u(cid:264)pienia z dok(cid:228)adno(cid:264)ci(cid:241) do nanosekund Zaawansowane zarz(cid:241)dzanie stanem u(cid:264)pienia Przeno(cid:264)ny sposób wprowadzania w stan u(cid:264)pienia Przepe(cid:228)nienia Alternatywy stanu u(cid:264)pienia Konwersje czasu Dostrajanie zegara systemowego Stan u(cid:264)pienia i oczekiwania Precyzyjne ustawianie czasu Zaawansowany interfejs ustawiania czasu Liczniki Proste alarmy Liczniki interwa(cid:228)owe Liczniki zaawansowane A Rozszerzenia kompilatora GCC dla j(cid:253)zyka C ............................................................ 401 B Bibliografia ................................................................................................................ 413 Skorowidz .................................................................................................................. 417 Spis tre(cid:316)ci (cid:95) 11 Kup książkęPoleć książkę 12 (cid:95) Spis tre(cid:316)ci Kup książkęPoleć książkę ROZDZIA(cid:292) 6. Zaawansowane zarz(cid:233)dzanie procesami W rozdziale 5. wyja(cid:264)niono, czym jest proces i jakich elementów systemu dotyczy. Omówiono tak(cid:276)e interfejsy j(cid:241)dra u(cid:276)yte w celu jego tworzenia, kontroli i usuwania. W niniejszym rozdziale informacje te s(cid:241) wykorzystane podczas rozwa(cid:276)a(cid:254) na temat zarz(cid:241)dcy procesów (ang. scheduler) i jego algorytmu szeregowania, by zaprezentowa(cid:232) zaawansowane interfejsy dla potrzeb zarz(cid:241)dzania procesami. Te funkcje systemowe ustalaj(cid:241) zachowanie szeregowania oraz semantyk(cid:246) procesu, wp(cid:228)ywaj(cid:241)c na sposób dzia(cid:228)ania zarz(cid:241)dcy procesów w d(cid:241)(cid:276)eniu do celu okre(cid:264)lonego przez apli- kacj(cid:246) lub u(cid:276)ytkownika. Szeregowanie procesów Zarz(cid:241)dca procesów jest sk(cid:228)adnikiem j(cid:241)dra, który dzieli ograniczony zasób czasu procesora pomi(cid:246)- dzy procesy systemowe. Innymi s(cid:228)owy, zarz(cid:241)dca procesów (lub mówi(cid:241)c pro(cid:264)ciej: zarz(cid:241)dca) jest podsystemem j(cid:241)dra, który decyduje, jaki proces powinien zosta(cid:232) uruchomiony w nast(cid:246)pnej kolejno(cid:264)ci. Podczas podejmowania decyzji, jakie procesy i kiedy maj(cid:241) by(cid:232) uruchomione, zarz(cid:241)dca jest odpowiedzialny za maksymalizowanie u(cid:276)ycia procesora oraz stwarzanie jednocze(cid:264)nie wra- (cid:276)enia, i(cid:276) wiele procesów jest wykonywanych wspó(cid:228)bie(cid:276)nie i p(cid:228)ynnie. W tym rozdziale b(cid:246)dzie mowa o procesach uruchamialnych (ang. runnable). Proces uruchamialny to taki proces, który nie jest zablokowany. Proces blokowany (ang. blocked) jest to taki proces, który znajduje si(cid:246) w stanie u(cid:264)pienia, czekaj(cid:241)c, a(cid:276) j(cid:241)dro rozpocznie wykonywanie operacji wej(cid:264)cia i wyj- (cid:264)cia. Procesy wspó(cid:228)dzia(cid:228)aj(cid:241)ce z u(cid:276)ytkownikami, intensywnie zapisuj(cid:241)ce lub czytaj(cid:241)ce pliki, a tak(cid:276)e odpowiadaj(cid:241)ce na sieciowe, maj(cid:241) tendencj(cid:246) do zu(cid:276)ywania du(cid:276)ej ilo(cid:264)ci czasu, kiedy s(cid:241) zablo- kowane podczas oczekiwania na zasoby, które maj(cid:241) sta(cid:232) si(cid:246) dost(cid:246)pne. Nie s(cid:241) one aktywne w czasie tych d(cid:228)ugich okresów bezczynno(cid:264)ci. W przypadku tylko jednego procesu urucha- mialnego zadanie zarz(cid:241)dcy procesów jest trywialne: uruchomi(cid:232) ten w(cid:228)a(cid:264)nie proces! Za- rz(cid:241)dca udowadnia swoj(cid:241) warto(cid:264)(cid:232) wówczas, gdy w systemie znajduje si(cid:246) wi(cid:246)cej procesów uruchamialnych ni(cid:276) procesorów. W takiej sytuacji niektóre procesy b(cid:246)d(cid:241) dzia(cid:228)a(cid:232), a inne musz(cid:241) czeka(cid:232) na swoj(cid:241) kolej. Zarz(cid:241)dca procesów bierze przede wszystkim odpowiedzialno(cid:264)(cid:232) za de- cyzj(cid:246), jaki proces, kiedy i na jak d(cid:228)ugi czas powinien zosta(cid:232) uruchomiony. System operacyjny zainstalowany w maszynie posiadaj(cid:241)cej pojedynczy procesor jest wielozada- niowy, gdy potrafi na przemian wykonywa(cid:232) wiele procesów, stwarzaj(cid:241)c z(cid:228)udzenie, i(cid:276) wi(cid:246)cej ni(cid:276) jeden proces dzia(cid:228)a w tym samym czasie. W maszynach wieloprocesorowych wielozadanio- wy system operacyjny pozwala procesom faktycznie dzia(cid:228)a(cid:232) równolegle na ró(cid:276)nych procesorach. System operacyjny, który nie jest wielozadaniowy, taki jak DOS, mo(cid:276)e uruchamia(cid:232) wy(cid:228)(cid:241)cz- nie jeden program w danym momencie. 193 Kup książkęPoleć książkę Wielozadaniowe systemy operacyjne dziel(cid:241) si(cid:246) na systemy kooperacyjne (ang. cooperative) oraz systemy z wyw(cid:228)aszczaniem (ang. preemptive). Linux implementuje drug(cid:241) form(cid:246) wielozadaniowo(cid:264)ci, w której zarz(cid:241)dca decyduje, kiedy nale(cid:276)y zatrzyma(cid:232) dany proces i uruchomi(cid:232) inny. Wyw(cid:228)aszcze- nie zwane jest te(cid:276) zawieszeniem dzia(cid:228)aj(cid:241)cego procesu. Jeszcze raz powtórzmy — d(cid:228)ugo(cid:264)(cid:232) czasu, w którym proces dzia(cid:228)a, zanim zarz(cid:241)dca go wyw(cid:228)aszczy, nazywany jest przedzia(cid:228)em czasowym procesu (dos(cid:228)owne t(cid:228)umaczenie: „plasterek czasu” — timeslice — nazywany tak z powodu przydziela- nia przez zarz(cid:241)dc(cid:246) ka(cid:276)demu procesowi uruchamialnemu „plasterka” czasu procesora). W wielozadaniowo(cid:264)ci kooperatywnej jest odwrotnie — proces nie przestaje dzia(cid:228)a(cid:232), dopóki sam nie zadecyduje o swoim zawieszeniu. Samoczynne zawieszenie si(cid:246) procesu nazywa si(cid:246) udo- st(cid:246)pnianiem czasu procesora (ang. yielding). W sytuacji idealnej procesy cz(cid:246)sto udost(cid:246)pniaj(cid:241) czas procesora, lecz system operacyjny jest niezdolny do wymuszenia tego zachowania. (cid:273)le dzia(cid:228)aj(cid:241)cy lub uszkodzony program mo(cid:276)e dzia(cid:228)a(cid:232) tak d(cid:228)ugo, (cid:276)e potrafi wyeliminowa(cid:232) iluzj(cid:246) wielozada- niowo(cid:264)ci, a nawet zawiesi(cid:232) ca(cid:228)y system. Z powodu tych problemów, zwi(cid:241)zanych z zagadnieniem wielozadaniowo(cid:264)ci, nowoczesne systemy operacyjne s(cid:241) generalnie wielozadaniowe z wyw(cid:228)asz- czaniem; Linux nie jest tu wyj(cid:241)tkiem. Zarz(cid:241)dca procesów Linuksa zmienia(cid:228) si(cid:246) na przestrzeni lat. Bie(cid:276)(cid:241)cym zarz(cid:241)dc(cid:241) procesów, dost(cid:246)p- nym od wersji 2.6.23 j(cid:241)dra Linuksa, jest Completely Fair Scheduler (w skrócie CFS). Jego nazwa pochodzi od s(cid:228)ów fair queuing (sprawiedliwe kolejkowanie) — nazwy algorytmu kolejkowania, który stara si(cid:246) sprawiedliwie udost(cid:246)pnia(cid:232) zasoby rywalizuj(cid:241)cym ze sob(cid:241) konsumentom. CFS ró(cid:276)ni si(cid:246) znacz(cid:241)co od innych uniksowych zarz(cid:241)dców procesów, w(cid:228)(cid:241)cznie z jego poprzednikiem, zarz(cid:241)dc(cid:241) procesów O(1). Zarz(cid:241)dc(cid:246) CFS omówimy dok(cid:228)adniej w podrozdziale „Completely Fair Scheduler”, znajduj(cid:241)cym si(cid:246) w dalszej cz(cid:246)(cid:264)ci tego rozdzia(cid:228)u. Przedzia(cid:293)y czasowe Przedzia(cid:228) czasowy, który zarz(cid:241)dca procesów przydziela ka(cid:276)demu procesowi, jest wa(cid:276)n(cid:241) warto(cid:264)ci(cid:241) dla ogólnego zachowania i sprawno(cid:264)ci systemu. Je(cid:264)li przedzia(cid:228)y czasowe s(cid:241) zbyt du(cid:276)e, procesy musz(cid:241) oczekiwa(cid:232) przez d(cid:228)ugi czas pomi(cid:246)dzy uruchomieniami, pogarszaj(cid:241)c wra(cid:276)enie równoleg(cid:228)e- go dzia(cid:228)ania. Mo(cid:276)e to by(cid:232) frustruj(cid:241)ce dla u(cid:276)ytkownika w przypadku zauwa(cid:276)alnych opó(cid:274)nie(cid:254). I na odwrót, je(cid:264)li przedzia(cid:228)y czasowe s(cid:241) zbyt ma(cid:228)e, znacz(cid:241)ca ilo(cid:264)(cid:232) czasu systemowego jest prze- znaczana na prze(cid:228)(cid:241)czanie mi(cid:246)dzy aplikacjami i traci si(cid:246) na przyk(cid:228)ad czasow(cid:241) lokalizacj(cid:246) (ang. temporal locality) i inne korzy(cid:264)ci. Ustalanie idealnego przedzia(cid:228)u czasowego nie jest wi(cid:246)c proste. Niektóre systemy operacyjne udzielaj(cid:241) procesom du(cid:276)ych przedzia(cid:228)ów czasowych, maj(cid:241)c nadziej(cid:246) na zwi(cid:246)kszenie przepusto- wo(cid:264)ci systemu oraz ogólnej wydajno(cid:264)ci. Inne systemy operacyjne daj(cid:241) procesom bardzo ma(cid:228)e przedzia(cid:228)y czasowe w nadziei, i(cid:276) zapewni(cid:241) systemowi bardzo dobr(cid:241) wydajno(cid:264)(cid:232). Jak si(cid:246) oka(cid:276)e, zarz(cid:241)dca CFS rozwi(cid:241)zuje ten problem w bardzo dziwny sposób: eliminuje przedzia(cid:228)y czasowe. Procesy zwi(cid:233)zane z wej(cid:316)ciem i wyj(cid:316)ciem a procesy zwi(cid:233)zane z procesorem Procesy, które w ci(cid:241)g(cid:228)y sposób konsumuj(cid:241) wszystkie mo(cid:276)liwe przedzia(cid:228)y czasowe im przydzie- lone, s(cid:241) okre(cid:264)lane mianem procesów zwi(cid:241)zanych z procesorem (ang. processor-bound). Takie procesy ci(cid:241)gle (cid:276)(cid:241)daj(cid:241) czasu procesora i b(cid:246)d(cid:241) konsumowa(cid:232) wszystko, co zarz(cid:241)dca im przydzieli. Najprost- szym, trywialnym tego przyk(cid:228)adem jest p(cid:246)tla niesko(cid:254)czona: 194 (cid:95) Rozdzia(cid:293) 6. Zaawansowane zarz(cid:233)dzanie procesami Kup książkęPoleć książkę // 100 zwi(cid:261)zanie z procesorem while (1) ; Inne, mniej ekstremalne przyk(cid:228)ady to obliczenia naukowe, matematyczne oraz przetwarzanie obrazów. Z drugiej strony, procesy, które przez wi(cid:246)kszo(cid:264)(cid:232) czasu s(cid:241) zablokowane w oczekiwaniu na jaki(cid:264) zasób, zamiast normalnie dzia(cid:228)a(cid:232), nazywane s(cid:241) procesami zwi(cid:241)zanymi z wej(cid:264)ciem i wyj(cid:264)ciem (ang. I/O-bound). Procesy zwi(cid:241)zane z wej(cid:264)ciem i wyj(cid:264)ciem s(cid:241) cz(cid:246)sto wznawiane i oczekuj(cid:241) w plikowych lub sieciowych operacjach zapisu i odczytu, blokuj(cid:241) si(cid:246) podczas oczekiwania na dane z klawiatury lub czekaj(cid:241) na akcj(cid:246) u(cid:276)ytkownika polegaj(cid:241)c(cid:241) na ruchu myszk(cid:241). Przyk(cid:228)ady aplikacji zwi(cid:241)zanych z wej(cid:264)ciem i wyj(cid:264)ciem to programy u(cid:276)ytkowe, które robi(cid:241) niewiele poza tym, (cid:276)e generuj(cid:241) wywo(cid:228)ania systemowe (cid:276)(cid:241)daj(cid:241)ce od j(cid:241)dra, aby wykona(cid:228) operacje wej(cid:264)cia i wyj- (cid:264)cia, takie jak cp lub mv, a tak(cid:276)e wiele aplikacji GUI, które zu(cid:276)ywaj(cid:241) du(cid:276)o czasu oczekuj(cid:241)c na akcj(cid:246) u(cid:276)ytkownika. Aplikacje zwi(cid:241)zane z procesorem oraz aplikacje zwi(cid:241)zane z wej(cid:264)ciem i wyj(cid:264)ciem chc(cid:241) wy- korzystywa(cid:232) takie opcje zarz(cid:241)dcy procesów, które najbardziej odpowiadaj(cid:241) ich sposobowi dzia(cid:228)ania. Aplikacje zwi(cid:241)zane z procesorem wymagaj(cid:241) mo(cid:276)liwie najwi(cid:246)kszych przedzia(cid:228)ów czasowych, pozwalaj(cid:241)cych im na poprawienie wspó(cid:228)czynnika u(cid:276)ywania pami(cid:246)ci podr(cid:246)cznej (poprzez czasow(cid:241) lokalizacj(cid:246)) oraz jak najszybciej ko(cid:254)cz(cid:241) swoje dzia(cid:228)anie. W przeciwie(cid:254)- stwie do nich procesy zwi(cid:241)zane z wej(cid:264)ciem i wyj(cid:264)ciem nie wymagaj(cid:241) koniecznie du(cid:276)ych prze- dzia(cid:228)ów czasowych, poniewa(cid:276) standardowo dzia(cid:228)aj(cid:241) tylko przez krótki czas przed wys(cid:228)aniem (cid:276)(cid:241)da(cid:254) zwi(cid:241)zanych z wej(cid:264)ciem i wyj(cid:264)ciem oraz blokowaniem si(cid:246) na jakim(cid:264) zasobie z j(cid:241)dra sys- temu. Procesy zwi(cid:241)zane z wej(cid:264)ciem i wyj(cid:264)ciem czerpi(cid:241) jednak korzy(cid:264)ci z tego, i(cid:276) zarz(cid:241)dca ob- s(cid:228)uguje je z wy(cid:276)szym priorytetem. Im szybciej jaka(cid:264) aplikacja mo(cid:276)e ponownie uruchomi(cid:232) si(cid:246) po zablokowaniu si(cid:246) i wys(cid:228)aniu wi(cid:246)kszej liczby (cid:276)(cid:241)da(cid:254) wej(cid:264)cia i wyj(cid:264)cia, tym lepiej potrafi ona u(cid:276)ywa(cid:232) urz(cid:241)dze(cid:254) systemowych. Co wi(cid:246)cej, im szybciej aplikacja czekaj(cid:241)ca na akcj(cid:246) u(cid:276)yt- kownika zostanie zaszeregowana, tym bardziej sprawia ona wra(cid:276)enie p(cid:228)ynnego dzia(cid:228)ania dla tego u(cid:276)ytkownika. Dopasowywanie potrzeb procesów zwi(cid:241)zanych z procesorem oraz wej(cid:264)ciem i wyj(cid:264)ciem nie jest (cid:228)atwe. W rzeczywisto(cid:264)ci wi(cid:246)kszo(cid:264)(cid:232) aplikacji stanowi po(cid:228)(cid:241)czenie procesów zwi(cid:241)zanych z proceso- rem oraz z wej(cid:264)ciem i wyj(cid:264)ciem. Kodowanie oraz dekodowanie strumieni d(cid:274)wi(cid:246)ku i obrazu jest dobrym przyk(cid:228)adem typu aplikacji, który opiera si(cid:246) jednoznacznej kwalifikacji. Wiele gier to równie(cid:276) aplikacje o typie mieszanym. Nie zawsze jest mo(cid:276)liwa identyfikacja sk(cid:228)onno(cid:264)ci da- nej aplikacji; w okre(cid:264)lonym momencie dany proces mo(cid:276)e zachowywa(cid:232) si(cid:246) w ró(cid:276)ny sposób. Szeregowanie z wyw(cid:293)aszczaniem W tradycyjnej metodzie szeregowania procesów w Uniksie wszystkim uruchamialnym procesom zostaje przydzielony przedzia(cid:228) czasu. Gdy dany proces wykorzysta swój przedzia(cid:228) czasowy, j(cid:241)- dro zawiesza go, a rozpoczyna wykonywanie innego procesu. Je(cid:264)li w systemie nie istnieje wi(cid:246)- cej procesów uruchamialnych, j(cid:241)dro pobiera grup(cid:246) procesów z wykorzystanymi przedzia(cid:228)ami czasowymi, uzupe(cid:228)nia te przedzia(cid:228)y oraz uruchamia procesy ponownie. Ca(cid:228)y proces jest powta- rzalny: procesy wci(cid:241)(cid:276) tworzone pojawiaj(cid:241) si(cid:246) na li(cid:264)cie procesów uruchamialnych, a procesy ko(cid:254)- czone s(cid:241) z niej usuwane, blokuj(cid:241) si(cid:246) na operacjach wej(cid:264)cia i wyj(cid:264)cia lub s(cid:241) budzone ze stanu u(cid:264)pienia. W ten sposób wszystkie procesy ostatecznie s(cid:241) uruchamiane, nawet je(cid:264)li w systemie istniej(cid:241) procesy o wy(cid:276)szym priorytecie; procesy niskopriorytetowe musz(cid:241) czeka(cid:232), a(cid:276) procesy Szeregowanie procesów (cid:95) 195 Kup książkęPoleć książkę o wysokim priorytecie wyczerpi(cid:241) swoje przedzia(cid:228)y czasowe lub zablokuj(cid:241) si(cid:246). To zachowanie formu(cid:228)uje wa(cid:276)n(cid:241), lecz ukryt(cid:241) regu(cid:228)(cid:246) szeregowania w systemach Unix: wszystkie procesy musz(cid:241) kontynuowa(cid:232) swoje dzia(cid:228)anie. Completely Fair Scheduler Zarz(cid:241)dca Completely Fair Scheduler (CFS) znacz(cid:241)co ró(cid:276)ni si(cid:246) od tradycyjnych zarz(cid:241)dców proce- sów spotykanych w systemie Unix. W wi(cid:246)kszo(cid:264)ci systemów uniksowych, w(cid:228)(cid:241)cznie z Linuk- sem przed wprowadzeniem CFS, istnia(cid:228)y dwie podstawowe zmienne, zwi(cid:241)zane z procesem podczas jego szeregowania: priorytet i przedzia(cid:228) czasu. Jak opisano we wcze(cid:264)niejszym pod- rozdziale w przypadku tradycyjnych zarz(cid:241)dców procesom przypisuje si(cid:246) przedzia(cid:228)y czaso- we, które reprezentuj(cid:241) „plasterek” procesora przydzielony dla nich. Procesory mog(cid:241) dzia(cid:228)a(cid:232) a(cid:276) do momentu, gdy wyczerpi(cid:241) ten przedzia(cid:228) czasowy. W podobny sposób procesom przypisuje si(cid:246) priorytet. Zarz(cid:241)dca uruchamia procesy o wy(cid:276)szym priorytecie przed tymi, które maj(cid:241) ni(cid:276)szy. Algorytm ten jest bardzo prosty i sprawdza(cid:228) si(cid:246) znakomicie w dawnych systemach uniksowych, które wymaga(cid:228)y podzia(cid:228)u czasu procesora. Nieco gorzej dzia(cid:228)a on w systemach wymagaj(cid:241)cych wysokiej wydajno(cid:264)ci interaktywnej oraz sprawiedliwego podzia(cid:228)u czasu, takich jak nowoczesne komputery stacjonarne i urz(cid:241)dzenia mobilne. W zarz(cid:241)dcy CFS u(cid:276)yto ca(cid:228)kiem innego algorytmu, zwanego sprawiedliwym kolejkowaniem (ang. fair scheduling), który eliminuje przedzia(cid:228)y czasu jako jednostki dost(cid:246)pu do procesora. Zamiast nich CFS przypisuje ka(cid:276)demu procesowi cz(cid:246)(cid:264)(cid:232) czasu procesora. Algorytm jest prosty: CFS rozpo- czyna swoje dzia(cid:228)anie poprzez przypisanie N procesom po 1/N czasu procesora. Nast(cid:246)pnie modyfikuje to przypisanie poprzez przydzielanie ka(cid:276)demu procesowi odpowiedniej wagi, zwi(cid:241)zanej z jego poziomem uprzejmo(cid:264)ci. Procesy z domy(cid:264)ln(cid:241) warto(cid:264)ci(cid:241) poziomu uprzejmo(cid:264)ci równ(cid:241) zero maj(cid:241) wag(cid:246) jeden, dlatego ich proporcja nie zostaje zmieniona. Procesy z mniejsz(cid:241) warto(cid:264)ci(cid:241) poziomu uprzejmo(cid:264)ci (wy(cid:276)szym priorytetem) uzyskuj(cid:241) wy(cid:276)sz(cid:241) wag(cid:246), wskutek czego zwi(cid:246)ksza si(cid:246) ich udzia(cid:228) w wykorzystaniu czasu procesora, podczas gdy procesy z wi(cid:246)ksz(cid:241) warto(cid:264)ci(cid:241) poziomu uprzejmo(cid:264)ci (ni(cid:276)szym priorytetem) otrzymuj(cid:241) ni(cid:276)sz(cid:241) wag(cid:246), a wi(cid:246)c zmniejsza si(cid:246) ich udzia(cid:228) w wykorzystaniu czasu procesora. Zarz(cid:241)dca CFS u(cid:276)ywa obecnie wa(cid:276)onej proporcji czasu procesora przypisanego do ka(cid:276)dego procesu. Aby ustali(cid:232) faktyczn(cid:241) d(cid:228)ugo(cid:264)(cid:232) odcinka czasu dzia(cid:228)ania dla ka(cid:276)dego procesu, CFS musi rozdzieli(cid:232) proporcje w okre(cid:264)lonym przedziale. Ten przedzia(cid:228) jest zwany docelowym opó(cid:274)nie- niem (ang. target latency), poniewa(cid:276) reprezentuje opó(cid:274)nienie szeregowania w systemie. Aby zro- zumie(cid:232) dzia(cid:228)anie docelowego opó(cid:274)nienia, za(cid:228)ó(cid:276)my, (cid:276)e zosta(cid:228)o ono zdefiniowane jako 20 mili- sekund, a w systemie znajduj(cid:241) si(cid:246) dwa uruchamialne procesy o tym samym priorytecie. Wynika z tego, (cid:276)e ka(cid:276)dy proces ma t(cid:246) sam(cid:241) wag(cid:246) i przypisano mu tak(cid:241) sam(cid:241) cz(cid:246)(cid:264)(cid:232) czasu procesora, czyli 10 milisekund. Tak wi(cid:246)c CFS uruchomi pierwszy proces na 10 milisekund, drugi równie(cid:276) na 10 milisekund, a nast(cid:246)pnie powtórzy ca(cid:228)(cid:241) operacj(cid:246). Je(cid:264)li w systemie by(cid:228)oby 5 procesów uruchamialnych, CFS przydziela(cid:228)by im po 4 milisekundy. Do tej pory wszystko wydaje si(cid:246) proste. Co si(cid:246) jednak stanie, gdy b(cid:246)dziemy mieli na przyk(cid:228)ad 200 procesów? Z docelowym opó(cid:274)nieniem wynosz(cid:241)cym 20 milisekund CFS b(cid:246)dzie móg(cid:228) uruchamia(cid:232) ka(cid:276)dy z tych procesów na jedynie 100 mikrosekund. Z powodu kosztów prze(cid:228)(cid:241)czania kon- tekstu (zwanych po prostu kosztami prze(cid:228)(cid:241)czania) pomi(cid:246)dzy procesorami oraz ograniczonej czasowej lokalizacji wydajno(cid:264)(cid:232) systemu mo(cid:276)e si(cid:246) pogorszy(cid:232). Aby rozwi(cid:241)za(cid:232) ten problem, 196 (cid:95) Rozdzia(cid:293) 6. Zaawansowane zarz(cid:233)dzanie procesami Kup książkęPoleć książkę CFS wprowadza drug(cid:241) kluczow(cid:241) zmienn(cid:241): minimaln(cid:241) ziarnisto(cid:264)(cid:232). Minimalna ziarnisto(cid:264)(cid:232) (ang. minimum granularity) jest najmniejszym przedzia(cid:228)em czasu, w jakim mo(cid:276)e dzia(cid:228)a(cid:232) dowolny proces. Wszystkie procesy, bez wzgl(cid:246)du na przydzielon(cid:241) im cz(cid:246)(cid:264)(cid:232) czasu procesora, b(cid:246)d(cid:241) dzia(cid:228)a(cid:232) z przy- najmniej minimaln(cid:241) ziarnisto(cid:264)ci(cid:241) (lub do czasu ich zablokowania). Dzi(cid:246)ki temu prze(cid:228)(cid:241)czanie nie poch(cid:228)ania nadmiernej ilo(cid:264)ci ca(cid:228)kowitego czasu systemu, dzieje si(cid:246) to jednak kosztem warto(cid:264)ci docelowego opó(cid:274)nienia. Oznacza to, (cid:276)e w przypadku gdy zaczyna by(cid:232) aktywna minimalna ziar- nisto(cid:264)(cid:232), zostaje naruszona zasada sprawiedliwego przydzielania czasu. Je(cid:264)li u(cid:276)yte zostan(cid:241) typowe warto(cid:264)ci docelowego opó(cid:274)nienia i minimalna ziarnisto(cid:264)(cid:232) oraz najcz(cid:246)(cid:264)ciej spotykana rozs(cid:241)dna liczba procesów uruchamialnych, minimalna ziarnisto(cid:264)(cid:232) nie zostaje aktywowana, docelowe opó(cid:274)nienie jest zachowywane, a zasada sprawiedliwego przydzielania czasu realizowana. Poprzez przydzielanie cz(cid:246)(cid:264)ci procesora, a nie sta(cid:228)ych przedzia(cid:228)ów czasowych, CFS mo(cid:276)e stoso- wa(cid:232) zasad(cid:246) sprawiedliwo(cid:264)ci: ka(cid:276)dy proces otrzymuje sprawiedliw(cid:241) cz(cid:246)(cid:264)(cid:232) procesora. Ponadto CFS potrafi u(cid:276)ywa(cid:232) konfigurowanego opó(cid:274)nienia szeregowania, poniewa(cid:276) docelowe opó(cid:274)nienie mo(cid:276)e by(cid:232) modyfikowane przez u(cid:276)ytkownika. W tradycyjnych zarz(cid:241)dcach uniksowych procesy z za(cid:228)o- (cid:276)enia dzia(cid:228)aj(cid:241) w sta(cid:228)ych przedzia(cid:228)ach czasowych, lecz opó(cid:274)nienie szeregowania (okre(cid:264)laj(cid:241)ce, jak cz(cid:246)sto s(cid:241) one uruchamiane) jest nieznane. W przypadku CFS procesy dzia(cid:228)aj(cid:241) zgodnie z przy- dzielonymi im cz(cid:246)(cid:264)ciami i z opó(cid:274)nieniem, a te warto(cid:264)ci z za(cid:228)o(cid:276)enia s(cid:241) znane. Jednak(cid:276)e przedzia(cid:228) czasowy zmienia si(cid:246), poniewa(cid:276) jest funkcj(cid:241) liczby uruchamialnych procesów w systemie. Jest to znacz(cid:241)co inna metoda obs(cid:228)ugi szeregowania procesów. Rozwi(cid:241)zuje ona wiele problemów dotycz(cid:241)cych procesów interaktywnych oraz zwi(cid:241)zanych z wej(cid:264)ciem i wyj(cid:264)ciem, n(cid:246)kaj(cid:241)cych tradycyjnych zarz(cid:241)dców procesów. Udost(cid:253)pnianie czasu procesora Chocia(cid:276) Linux jest wielozadaniowym systemem operacyjnym z wyw(cid:228)aszczaniem, dostarcza równie(cid:276) funkcj(cid:246) systemow(cid:241), która pozwala procesom jawnie zawiesza(cid:232) dzia(cid:228)anie i informowa(cid:232) zarz(cid:241)dc(cid:246), by wybra(cid:228) nowy proces do uruchomienia: #include sched.h int sched_yield (void); Wywo(cid:228)anie funkcji sched_yield() skutkuje zawieszeniem aktualnie dzia(cid:228)aj(cid:241)cego procesu, po czym zarz(cid:241)dca procesów wybiera nowy proces, aby go uruchomi(cid:232), w taki sam sposób, jakby j(cid:241)dro samo wyw(cid:228)aszczy(cid:228)o aktualny proces w celu uruchomienia nowego. Warte uwagi jest to, (cid:276)e je(cid:264)li nie istnieje (cid:276)aden inny proces uruchamialny, co jest cz(cid:246)stym przypadkiem, wówczas proces udost(cid:246)pniaj(cid:241)cy natychmiast ponowi swoje dzia(cid:228)anie. Z powodu przypadkowo(cid:264)ci po(cid:228)(cid:241)- czonej z ogólnym przekonaniem, i(cid:276) zazwyczaj istniej(cid:241) lepsze metody, u(cid:276)ycie tego wywo(cid:228)ania systemowego nie jest popularne. W przypadku sukcesu funkcja zwraca 0; w przypadku pora(cid:276)ki zwraca –1 oraz ustawia errno na odpowiedni(cid:241) warto(cid:264)(cid:232) kodu b(cid:228)(cid:246)du. W Linuksie oraz — bardziej ni(cid:276) prawdopodobnie — w wi(cid:246)k- szo(cid:264)ci systemów Unix wywo(cid:228)anie funkcji sched_yield() nie mo(cid:276)e si(cid:246) nie uda(cid:232) i dlatego te(cid:276) zawsze zwraca warto(cid:264)(cid:232) zero. Drobiazgowy programista mo(cid:276)e jednak ci(cid:241)gle próbowa(cid:232) sprawdza(cid:232) zwracan(cid:241) warto(cid:264)(cid:232): if (sched_yield ( )) perror ( sched_yield ); Udost(cid:253)pnianie czasu procesora (cid:95) 197 Kup książkęPoleć książkę Prawid(cid:293)owe sposoby u(cid:348)ycia sched_yield() W praktyce istnieje kilka prawid(cid:228)owych sposobów u(cid:276)ycia funkcji sched_yield() w poprawnym wielozadaniowym systemie z wyw(cid:228)aszczeniem, jak na przyk(cid:228)ad w Linuksie. J(cid:241)dro jest w pe(cid:228)ni zdolne do podj(cid:246)cia optymalnych oraz najbardziej efektywnych decyzji dotycz(cid:241)cych szeregowania — oczywi(cid:264)cie, j(cid:241)dro jest lepiej ni(cid:276) sama aplikacja wyposa(cid:276)one w mechanizmy, które pozwalaj(cid:241) decydowa(cid:232), co i kiedy nale(cid:276)y wyw(cid:228)aszczy(cid:232). Oto, dlaczego w systemach operacyjnych odchodzi si(cid:246) od wielozadaniowo(cid:264)ci kooperatywnej na rzecz wielozadaniowo(cid:264)ci z wyw(cid:228)aszczeniem. Dlaczego wi(cid:246)c w ogóle istnieje funkcja systemowa „Przeszereguj mnie”? Odpowied(cid:274) mo(cid:276)na znale(cid:274)(cid:232) w aplikacjach oczekuj(cid:241)cych na zdarzenia zewn(cid:246)trzne, które mog(cid:241) by(cid:232) spowodowane przez u(cid:276)ytkownika, element sprz(cid:246)towy albo inny proces. Na przyk(cid:228)ad, je(cid:264)li jeden proces musi czeka(cid:232) na inny, pierwszym narzucaj(cid:241)cym si(cid:246) rozwi(cid:241)zaniem tego problemu jest: „po prostu udo- st(cid:246)pnij czas procesora, dopóki inny proces si(cid:246) nie zako(cid:254)czy”. Jako przyk(cid:228)ad mog(cid:228)aby wyst(cid:241)pi(cid:232) implementacja prostego konsumenta w parze producent-konsument, która by(cid:228)aby podobna do nast(cid:246)puj(cid:241)cego kodu: /* konsument… */ do { while (producer_not_ready ()) sched_yield (); process_data (); } while (!time_to_quit()); Na szcz(cid:246)(cid:264)cie programi(cid:264)ci systemu Unix nie s(cid:241) sk(cid:228)onni do tworzenia kodu tego typu. Programy uniksowe s(cid:241) zwykle sterowane zdarzeniami i zamiast stosowa(cid:232) funkcj(cid:246) sched_yield() d(cid:241)(cid:276)(cid:241) do u(cid:276)ywania pewnego rodzaju mechanizmu blokowania (takiego jak potok — ang. pipe) pomi(cid:246)- dzy konsumentem a producentem. W tym przypadku konsument próbuje czyta(cid:232) z potoku, b(cid:246)d(cid:241)c jednak zablokowanym, dopóki nie pojawi(cid:241) si(cid:246) dane. Z drugiej strony, producent zapi- suje do potoku, gdy tylko dost(cid:246)pne staj(cid:241) si(cid:246) nowe dane. Przenosi to odpowiedzialno(cid:264)(cid:232) za koor- dynacj(cid:246) z procesu nale(cid:276)(cid:241)cego do poziomu u(cid:276)ytkownika, na przyk(cid:228)ad z p(cid:246)tli zajmuj(cid:241)cych czas procesora do j(cid:241)dra, które mo(cid:276)e optymalnie zarz(cid:241)dza(cid:232) tak(cid:241) sytuacj(cid:241) przez prze(cid:228)(cid:241)czanie proce- sów w stan u(cid:264)pienia oraz budzenie ich tylko w przypadku potrzeby. Ogólnie rzecz bior(cid:241)c, programy uniksowe powinny d(cid:241)(cid:276)y(cid:232) do rozwi(cid:241)za(cid:254) sterowanych zdarzeniami, które opieraj(cid:241) si(cid:246) na blokowanych deskryptorach plików. Jedna sytuacja do niedawna koniecznie wymaga(cid:228)a sched_yield() — blokowanie w(cid:241)tku z poziomu u(cid:276)ytkownika. Gdy jaki(cid:264) w(cid:241)tek próbowa(cid:228) uzyska(cid:232) blokad(cid:246), która jest ju(cid:276) w posiadaniu innego w(cid:241)tku, wówczas udost(cid:246)pnia(cid:228) on czas procesora dopóty, dopóki blokada nie zosta(cid:228)a zwol- niona. Bez wsparcia blokad z poziomu u(cid:276)ytkownika ze strony j(cid:241)dra to podej(cid:264)cie by(cid:228)o najprostsze i najbardziej efektywne. Na szcz(cid:246)(cid:264)cie nowoczesna implementacja w(cid:241)tków w Linuksie (Native PO- SIX Threading Library — NPTL) wprowadzi(cid:228)a optymalne rozwi(cid:241)zanie przy u(cid:276)yciu mechanizmu futex, który dostarcza procesorowi wsparcia dla systemu blokowania z poziomu u(cid:276)ytkownika. Jeszcze innym przyk(cid:228)adem u(cid:276)ycia funkcji sched_yield() jest zagadnienie „sympatycznego dzia(cid:228)ania”: program intensywnie obci(cid:241)(cid:276)aj(cid:241)cy procesor mo(cid:276)e wywo(cid:228)ywa(cid:232) co jaki(cid:264) czas sched_yield(), przez co minimalizuje swoje obci(cid:241)(cid:276)enie w systemie. Rozwi(cid:241)zanie to ma by(cid:232) mo(cid:276)e szlachetny cel, lecz niestety posiada dwie wady. Po pierwsze, j(cid:241)dro potrafi podejmowa(cid:232) globalne decyzje dotycz(cid:241)ce szeregowania du(cid:276)o lepiej ni(cid:276) indywidualne procesy i w konsekwen- cji odpowiedzialno(cid:264)(cid:232) za zapewnienie p(cid:228)ynno(cid:264)ci operacji w systemie powinna spoczywa(cid:232) na zarz(cid:241)dcy procesów, a nie na samych procesach. Po drugie, za zmniejszenie obci(cid:241)(cid:276)enia aplikacji 198 (cid:95) Rozdzia(cid:293) 6. Zaawansowane zarz(cid:233)dzanie procesami Kup książkęPoleć książkę korzystaj(cid:241)cej intensywnie z procesora z jednoczesnym wyró(cid:276)nieniem innych programów od- powiada u(cid:276)ytkownik, a nie pojedyncza aplikacja. U(cid:276)ytkownik mo(cid:276)e zmodyfikowa(cid:232) swoje preferencje dotycz(cid:241)ce wydajno(cid:264)ci aplikacji poprzez u(cid:276)ycie komendy pow(cid:228)oki systemowej nice, która b(cid:246)dzie omawiana w dalszej cz(cid:246)(cid:264)ci tego rozdzia(cid:228)u. Priorytety procesu Dyskusja w tym podrozdziale dotyczy zwyk(cid:228)ych procesów, nieb(cid:246)d(cid:241)cych procesami czasu rzeczywistego. Procesy czasu rzeczywistego wymagaj(cid:241) odmiennych kryteriów szeregowania oraz oddzielnego systemu priorytetów. B(cid:246)dzie to omówione w dalszej cz(cid:246)(cid:264)ci rozdzia(cid:228)u. Linux nie szereguje procesów w sposób przypadkowy. Zamiast tego procesom przypisywane s(cid:241) priorytety, które wp(cid:228)ywaj(cid:241) na czas ich dzia(cid:228)ania: jak pami(cid:246)tasz, cz(cid:246)(cid:264)(cid:232) procesora przypisana do procesu jest wa(cid:276)ona przy u(cid:276)yciu warto(cid:264)ci poziomu uprzejmo(cid:264)ci. Od pocz(cid:241)tku swojego istnie- nia Unix nazywa(cid:228) te priorytety poziomami uprzejmo(cid:264)ci (ang. nice values), poniewa(cid:276) ide(cid:241) ukryt(cid:241) za t(cid:241) nazw(cid:241) by(cid:228)o to, aby „by(cid:232) uprzejmym” dla innych procesów znajduj(cid:241)cych si(cid:246) w systemie poprzez obni(cid:276)anie priorytetu aktualnego procesu, zezwalaj(cid:241)c przez to innym procesom na konsumowanie wi(cid:246)kszej ilo(cid:264)ci czasu procesora. Poprawne poziomy uprzejmo(cid:264)ci zawieraj(cid:241) si(cid:246) w granicach od –20 do 19 w(cid:228)(cid:241)cznie, z domy(cid:264)ln(cid:241) warto(cid:264)ci(cid:241) równ(cid:241) zeru. W pewien sposób dezorientuj(cid:241)ce jest to, i(cid:276) im ni(cid:276)szy poziom uprzej- mo(cid:264)ci dla danego procesu, tym wy(cid:276)szy jego priorytet oraz wi(cid:246)kszy przedzia(cid:228) czasu; odwrotnie, im wy(cid:276)sza warto(cid:264)(cid:232), tym ni(cid:276)szy priorytet procesu i mniejszy przedzia(cid:228) czasu. Dlatego te(cid:276) zwi(cid:246)k- szanie poziomu uprzejmo(cid:264)ci dla procesu jest „uprzejme” dla reszty systemu. Odwrócenie warto(cid:264)ci liczbowych wprawia niestety w zak(cid:228)opotanie. Gdy mówi si(cid:246), (cid:276)e proces ma „wy(cid:276)szy priorytet”, oznacza to, (cid:276)e cz(cid:246)(cid:264)ciej zostaje wybrany do uruchomienia i mo(cid:276)e dzia(cid:228)a(cid:232) d(cid:228)u(cid:276)ej ni(cid:276) procesy niskopriorytetowe. Taki proces posiada jednak ni(cid:276)szy poziom uprzejmo(cid:264)ci. nice() Linux dostarcza kilka funkcji systemowych w celu odczytania oraz ustawienia poziomu uprzej- mo(cid:264)ci dla procesu. Najprostsz(cid:241) z nich jest funkcja nice(): #include unistd.h int nice (int inc); Udane wywo(cid:228)anie funkcji nice() zwi(cid:246)ksza poziom uprzejmo(cid:264)ci procesu o liczb(cid:246) przeka- zan(cid:241) przez parametr inc oraz zwraca uaktualnion(cid:241) warto(cid:264)(cid:232). Tylko proces z uprawnieniami CAP_SYS_NICE (w rzeczywisto(cid:264)ci proces, którego w(cid:228)a(cid:264)cicielem jest administrator) mo(cid:276)e prze- kazywa(cid:232) ujemn(cid:241) warto(cid:264)(cid:232) w parametrze inc, zmniejszaj(cid:241)c swój poziom uprzejmo(cid:264)ci i przez to zwi(cid:246)kszaj(cid:241)c swój priorytet. Zgodnie z tym procesy nieb(cid:246)d(cid:241)ce procesami nale(cid:276)(cid:241)cymi do administratora mog(cid:241) jedynie obni(cid:276)a(cid:232) swój priorytet (poprzez zwi(cid:246)kszanie swojego pozio- mu uprzejmo(cid:264)ci). W przypadku b(cid:228)(cid:246)du wykonania nice() zwraca warto(cid:264)(cid:232) –1. Poniewa(cid:276) jednak nice() zwraca no- w(cid:241) warto(cid:264)(cid:232) poziomu uprzejmo(cid:264)ci, –1 jest równocze(cid:264)nie poprawn(cid:241) warto(cid:264)ci(cid:241) zwrotn(cid:241). Aby od- ró(cid:276)ni(cid:232) poprawne wywo(cid:228)anie od b(cid:228)(cid:246)dnego, mo(cid:276)na wyzerowa(cid:232) warto(cid:264)(cid:232) errno przed wykona- niem wywo(cid:228)ania, a nast(cid:246)pnie j(cid:241) sprawdzi(cid:232). Na przyk(cid:228)ad: Priorytety procesu (cid:95) 199 Kup książkęPoleć książkę int ret; errno = 0; ret = nice (10); /* zwi(cid:266)ksz nasz poziom uprzejmo(cid:286)ci o 10 */ if (ret == -1 errno != 0) perror ( nice ); else printf ( Poziom uprzejmo(cid:321)ci wynosi aktualnie d\n , ret); Linux zwraca tylko jeden kod b(cid:228)(cid:246)du: EPERM, informuj(cid:241)c, i(cid:276) proces wywo(cid:228)uj(cid:241)cy spróbowa(cid:228) zwi(cid:246)k- szy(cid:232) swój priorytet (poprzez ujemn(cid:241) warto(cid:264)(cid:232) parametru inc), lecz nie posiada(cid:228) uprawnienia CAP_SYS_NICE. Inne systemy zwracaj(cid:241) równie(cid:276) kod b(cid:228)(cid:246)du EINVAL, gdy inc próbuje ustali(cid:232) now(cid:241) warto(cid:264)(cid:232) poziomu uprzejmo(cid:264)ci poza dopuszczalnym zakresem, lecz Linux tego nie robi. Zamiast tego Linux zaokr(cid:241)gla niew(cid:228)a(cid:264)ciwe warto(cid:264)ci inc w razie potrzeby w gór(cid:246) lub w dó(cid:228) do wielko(cid:264)ci b(cid:246)d(cid:241)cej odpowiedni(cid:241) granic(cid:241) dopuszczalnego zakresu. Przekazanie zera w parametrze inc jest prostym sposobem na uzyskanie aktualnej warto(cid:264)ci poziomu uprzejmo(cid:264)ci: printf ( Poziom uprzejmo(cid:321)ci wynosi obecnie d\n , nice (0)); Cz(cid:246)sto proces chce ustawi(cid:232) bezwzgl(cid:246)dn(cid:241) warto(cid:264)(cid:232) poziomu uprzejmo(cid:264)ci, zamiast przekazywa(cid:232) wzgl(cid:246)dn(cid:241) wielko(cid:264)(cid:232) ró(cid:276)nicy. Mo(cid:276)na to uzyska(cid:232) poprzez wykonanie poni(cid:276)szego kodu: int ret, val; /* pobierz aktualn(cid:261) warto(cid:286)(cid:252) poziomu uprzejmo(cid:286)ci */ val = nice (0); /* chcemy ustawi(cid:252) poziom uprzejmo(cid:286)ci na 10 */ val = 10 - val; errno = 0; ret = nice (val); if (ret == -1 errno != 0) perror ( nice ); else printf ( Poziom uprzejmo(cid:321)ci wynosi aktualnie d\n , ret); getpriority() i setpriority() Preferowanym rozwi(cid:241)zaniem jest u(cid:276)ycie funkcji systemowych getpriority() oraz setpriori- ty(), które udost(cid:246)pniaj(cid:241) wi(cid:246)cej mo(cid:276)liwo(cid:264)ci kontroli, lecz s(cid:241) bardziej z(cid:228)o(cid:276)one w dzia(cid:228)aniu: #include sys/time.h #include sys/resource.h int getpriority (int which, int who); int setpriority (int which, int who, int prio); Funkcje te dzia(cid:228)aj(cid:241) na procesie, grupie procesów lub u(cid:276)ytkowniku, co odpowiednio ustalaj(cid:241) parametry which oraz who. Parametr which musi posiada(cid:232) jedn(cid:241) z nast(cid:246)puj(cid:241)cych warto(cid:264)ci: PRIO_PROCESS, PRIO_PGRP lub PRIO_USER; w tym przypadku parametr who okre(cid:264)la odpowied- nio identyfikator procesu, identyfikator grupy procesów lub identyfikator u(cid:276)ytkownika. Wywo(cid:228)anie funkcji getpriority() zwraca najwy(cid:276)szy priorytet (najni(cid:276)sz(cid:241) liczbow(cid:241) warto(cid:264)(cid:232) poziomu uprzejmo(cid:264)ci) dla ka(cid:276)dego z podanych procesów. Wywo(cid:228)anie funkcji setpriority() ustawia priorytet wszystkich podanych procesów na warto(cid:264)(cid:232) prio. Podobnie jak w przypadku funkcji nice(), tylko proces posiadaj(cid:241)cy uprawnienia CAP_SYS_NICE mo(cid:276)e zwi(cid:246)kszy(cid:232) priorytet 200 (cid:95) Rozdzia(cid:293) 6. Zaawansowane zarz(cid:233)dzanie procesami Kup książkęPoleć książkę procesu (zmniejszy(cid:232) liczbow(cid:241) warto(cid:264)(cid:232) poziomu uprzejmo(cid:264)ci). Co wi(cid:246)cej, tylko proces z tym uprawnieniem mo(cid:276)e zwi(cid:246)kszy(cid:232) lub zmniejszy(cid:232) priorytet procesu nieb(cid:246)d(cid:241)cego w posiadaniu przez wywo(cid:228)uj(cid:241)cego go u(cid:276)ytkownika. Podobnie jak nice(), równie(cid:276) getpriority() zwraca –1 w przypadku b(cid:228)(cid:246)du. Poniewa(cid:276) jest to równie(cid:276) poprawna warto(cid:264)(cid:232) zwrotna, programi(cid:264)ci powinni zerowa(cid:232) errno przed wywo(cid:228)aniem funkcji, je(cid:264)li zamierzaj(cid:241) obs(cid:228)ugiwa(cid:232) przypadki b(cid:228)(cid:246)dów. Wywo(cid:228)anie setpriority() nie powo- duje takich problemów —setpriority() zawsze zwraca 0 w przypadku powodzenia, nato- miast –1 w przypadku niepowodzenia. Nast(cid:246)puj(cid:241)cy kod zwraca aktualn(cid:241) warto(cid:264)(cid:232) priorytetu procesu: int ret; ret = getpriority (PRIO_PROCESS, 0); printf ( Poziom uprzejmo(cid:321)ci wynosi d\n , ret); Poni(cid:276)szy kod ustawia priorytet dla wszystkich procesów z aktualnej grupy procesów na war- to(cid:264)(cid:232) 10: int ret; ret = setpriority (PRIO_PGRP, 0, 10); if (ret == -1) perror ( setpriority ); W przypadku b(cid:228)(cid:246)du obie funkcje ustawiaj(cid:241) errno na jedn(cid:241) z poni(cid:276)szych warto(cid:264)ci: EACCES Proces zamierza(cid:228) zwi(cid:246)kszy(cid:232) priorytet, lecz nie posiada uprawnienia CAP_SYS_NICE (tylko dla setpriority()). EINVAL Warto(cid:264)(cid:232) przekazana przez parametr which nie by(cid:228)a jedn(cid:241) z nast(cid:246)puj(cid:241)cych: PRIO_PROCESS, PRIO_PGRP lub PRIO_USER. EPERM Efektywny identyfikator u(cid:276)ytkownika procesu branego pod uwag(cid:246) nie zgadza si(cid:246) z efek- tywnym identyfikatorem u(cid:276)ytkownika procesu dzia(cid:228)aj(cid:241)cego; proces dzia(cid:228)aj(cid:241)cy dodatkowo nie posiada uprawnienia CAP_SYS_NICE (tylko dla setpriority()). ESRCH Nie znaleziono procesu spe(cid:228)niaj(cid:241)cego wymaga(cid:254), które zosta(cid:228)y okre(cid:264)lone przez parametry which oraz who. Priorytety wej(cid:316)cia i wyj(cid:316)cia W ramach dodatku do priorytetów szeregowania Linux pozwala procesom okre(cid:264)li(cid:232) priorytety wej(cid:264)cia i wyj(cid:264)cia. Ta warto(cid:264)(cid:232) wp(cid:228)ywa na wzgl(cid:246)dny priorytet (cid:276)(cid:241)da(cid:254) wej(cid:264)cia i wyj(cid:264)cia dla proce- sów. Zarz(cid:241)dca wej(cid:264)cia i wyj(cid:264)cia z j(cid:241)dra systemu (omówiony w rozdziale 4.) obs(cid:228)uguje (cid:276)(cid:241)dania pochodz(cid:241)ce z procesów o wy(cid:276)szym priorytecie wej(cid:264)cia i wyj(cid:264)cia przed (cid:276)(cid:241)daniami z procesów o ni(cid:276)szym priorytecie wej(cid:264)cia i wyj(cid:264)cia. Zarz(cid:241)dcy wej(cid:264)cia i wyj(cid:264)cia domy(cid:264)lnie wykorzystuj(cid:241) poziom uprzejmo(cid:264)ci procesu, aby ustali(cid:232) priorytet wej(cid:264)cia i wyj(cid:264)cia. Dlatego te(cid:276) ustawienie poziomu uprzejmo(cid:264)ci automatycznie zmie- nia priorytet wej(cid:264)cia i wyj(cid:264)cia. J(cid:241)dro Linuksa dostarcza jednak(cid:276)e dodatkowo dwóch funkcji systemowych, w celu jawnego ustawienia i uzyskania informacji dotycz(cid:241)cych priorytetu wej(cid:264)cia i wyj(cid:264)cia, niezale(cid:276)nie od warto(cid:264)ci poziomu uprzejmo(cid:264)ci: Priorytety procesu (cid:95) 201 Kup książkęPoleć książkę int ioprio_get (int which, int who) int ioprio_set (int which, int who, int ioprio) Niestety biblioteka glibc nie umo(cid:276)liwia (cid:276)adnego dost(cid:246)pu do tych funkcji z poziomu u(cid:276)ytkownika. Bez wsparcia przez glibc u(cid:276)ywanie ich jest w najlepszym przypadku niewygodne. Co wi(cid:246)cej, w momencie, gdy biblioteka glibc zacznie udziela(cid:232) wsparcia, mo(cid:276)e zdarzy(cid:232) si(cid:246), i(cid:276) jej interfejs nie b(cid:246)dzie kompatybilny z tymi funkcjami. Dopóki nie ma takiego wsparcia, istniej(cid:241) dwa przeno(cid:264)ne sposoby pozwalaj(cid:241)ce modyfikowa(cid:232) priorytety wej(cid:264)cia i wyj(cid:264)cia: poprzez poziomy uprzejmo(cid:264)ci lub program u(cid:276)ytkowy o nazwie ionice, który jest sk(cid:228)adnikiem pakietu util-linux1. Nie wszyscy zarz(cid:241)dcy wej(cid:264)cia i wyj(cid:264)cia wspieraj(cid:241) priorytety wej(cid:264)cia i wyj(cid:264)cia. Wyj(cid:241)tkiem jest zarz(cid:241)dca wej(cid:264)cia i wyj(cid:264)cia o nazwie Complete Fair Queuing (CFQ); inni typowi zarz(cid:241)dcy aktu- alnie nie posiadaj(cid:241) wsparcia dla priorytetów wej(cid:264)cia i wyj(cid:264)cia. W przypadku, gdy dany zarz(cid:241)dca wej(cid:264)cia i wyj(cid:264)cia nie wspiera priorytetów wej(cid:264)cia i wyj(cid:264)cia, s(cid:241) one przez niego milcz(cid:241)co pomijane. Wi(cid:233)zanie procesów do konkretnego procesora Linux wspiera wieloprocesorowo(cid:264)(cid:232) dla pojedynczego systemu. Poza procesem (cid:228)adowania sys- temu wi(cid:246)kszo(cid:264)(cid:232) pracy niezb(cid:246)dnej dla zapewnienia poprawnego dzia(cid:228)ania systemu wielo- procesorowego zrzucona jest na zarz(cid:241)dc(cid:246) procesów. Na maszynie wieloprocesorowej zarz(cid:241)dca procesów musi decydowa(cid:232), który proces powinien uruchamia(cid:232) na ka(cid:276)dym procesorze. Z tej odpowiedzialno(cid:264)ci wynikaj(cid:241) dwa wyzwania: zarz(cid:241)dca musi d(cid:241)(cid:276)y(cid:232) do tego, aby w pe(cid:228)ni wykorzystywa(cid:232) wszystkie procesory w systemie, poniewa(cid:276) sytuacja, gdy procesor jest nieobci(cid:241)(cid:276)o- ny, a proces oczekuje na uruchomienie, prowadzi do nieefektywnego dzia(cid:228)ania. Gdy jednak pro- ces zosta(cid:228) zaszeregowany dla okre(cid:264)lonego procesora, zarz(cid:241)dca procesów powinien d(cid:241)(cid:276)y(cid:232), aby szeregowa(cid:232) go do tego samego procesora równie(cid:276) w przysz(cid:228)o(cid:264)ci. Jest to korzystne, gdy(cid:276) migracja procesu z jednego procesora do innego poci(cid:241)ga za sob(cid:241) pewne koszty. Najwi(cid:246)ksza cz(cid:246)(cid:264)(cid:232) tych kosztów dotyczy skutków buforowania (ang. cache effects) podczas migracji. Z powodu okre(cid:264)lonych konstrukcji nowoczesnych systemów SMP wi(cid:246)kszo(cid:264)(cid:232) pami(cid:246)ci podr(cid:246)cz- nych przy(cid:228)(cid:241)czonych do ka(cid:276)dego procesora jest niezale(cid:276)na i oddzielona od siebie. Oznacza to, (cid:276)e dane z jednej pami(cid:246)ci podr(cid:246)cznej nie powielaj(cid:241) si(cid:246) w innej. Dlatego te(cid:276), je(cid:264)li proces przenosi si(cid:246) do nowego procesora i zapisuje nowe informacje w pami(cid:246)ci, dane w pami(cid:246)ci podr(cid:246)cznej po- przedniego procesora mog(cid:241) straci(cid:232) aktualno(cid:264)(cid:232). Poleganie na tej pami(cid:246)ci podr(cid:246)cznej mo(cid:276)e wówczas spowodowa(cid:232) uszkodzenie danych. Aby temu przeciwdzia(cid:228)a(cid:232), pami(cid:246)ci podr(cid:246)czne unie- wa(cid:276)niaj(cid:241) ka(cid:276)de inne dane, ilekro(cid:232) buforuj(cid:241) nowy fragment pami(cid:246)ci. Zgodnie z tym okre(cid:264)lony fragment danych znajduje si(cid:246) dok(cid:228)adnie tylko w jednej pami(cid:246)ci podr(cid:246)cznej procesora w da- nym momencie (zak(cid:228)adaj(cid:241)c, (cid:276)e dane s(cid:241) w ogóle buforowane). Gdy proces przenosi si(cid:246) z jed- nego procesora do innego, poci(cid:241)ga to za sob(cid:241) nast(cid:246)puj(cid:241)ce koszty: dane buforowane nie s(cid:241) ju(cid:276) dost(cid:246)pne dla procesu, który si(cid:246) przeniós(cid:228), a dane w (cid:274)ród(cid:228)owym procesorze musz(cid:241) by(cid:232) unie- wa(cid:276)nione. Z powodu tych kosztów zarz(cid:241)dca procesów próbuje utrzyma(cid:232) proces na okre(cid:264)lonym procesorze tak d(cid:228)ugo, jak to jest mo(cid:276)liwe. Dwa cele zarz(cid:241)dcy procesów s(cid:241) oczywi(cid:264)cie potencjalnie sprzeczne ze sob(cid:241). Je(cid:264)li jeden proce- sor jest znacz(cid:241)co bardziej obci(cid:241)(cid:276)ony ni(cid:276) drugi albo, co gorsza, je(cid:264)li jeden procesor jest ca(cid:228)ko- wicie zaj(cid:246)ty, podczas gdy drugi jest bezczynny, wówczas zaczyna mie(cid:232) sens przeszeregowanie 1 Pakiet util-linux jest osi(cid:241)galny pod adresem http://kernel.org. Jest on licencjonowany zgodnie z Powszechn(cid:241) Li- cencj(cid:241) Publiczn(cid:241) GNU w wersji 2. 202 (cid:95) Rozdzia(cid:293) 6. Zaawansowane zarz(cid:233)dzanie procesami Kup książkęPoleć książkę niektórych procesów do procesora mniej obci(cid:241)(cid:276)onego. Decyzja, kiedy nale(cid:276)y przenie(cid:264)(cid:232) procesy w przypadku takiego braku równowagi, zwana wyrównywaniem obci(cid:241)(cid:276)enia, odgrywa bardzo wa(cid:276)n(cid:241) rol(cid:246) w wydajno(cid:264)ci maszyn SMP. Wi(cid:241)zanie procesów dla konkretnego procesora odnosi si(cid:246) do prawdopodobie(cid:254)stwa, (cid:276)e proces zostanie konsekwentnie zaszeregowany do tego samego procesora. Termin mi(cid:246)kkie wi(cid:241)zanie (ang. soft affinity) okre(cid:264)la naturaln(cid:241) sk(cid:228)onno(cid:264)(cid:232) zarz(cid:241)dcy, aby kontynuowa(cid:232) szeregowanie procesu na tym samym procesorze. Jak ju(cid:276) powiedziano, jest to warto(cid:264)ciowa cecha. Zarz(cid:241)dca linuksowy szereguje te same procesy na tych samych procesorach przez tak d(cid:228)ugi czas, jak to jest mo(cid:276)liwe, przenosz(cid:241)c proces z jednego procesora na inny jedynie w przypadku wyj(cid:241)tkowego braku równowagi. Pozwala to zarz(cid:241)dcy zmniejsza(cid:232) skutki buforowania w przypadku migracji proce- sów i zapewnia, (cid:276)e wszystkie procesory w systemie s(cid:241) równo obci(cid:241)(cid:276)one. Czasami jednak u(cid:276)ytkownik lub aplikacja chc(cid:241) wymusi(cid:232) powi(cid:241)zanie proces-procesor. Dzieje si(cid:246) tak cz(cid:246)sto, gdy sam proces jest wra(cid:276)liwy na
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Linux. Programowanie systemowe. Wydanie II
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: