[email protected] - kolos wikikolos.math.uni.lodz.pl/~archive/systemy operacyjne/calosc -...

48
Systemy operacyjne 1 [email protected] B203, dyżur środa 14-16 Będzie mowa o teorii systemów operacyjnych i będą przykłady z konkretnych rozwiązań, będzie wykład oderwany od wszelkich nazw własnych, czyli będzie co innego niż na ćw. Wykład nie będzie miał charakteru narzędziowego. Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach znajdują się tutaj nieświeże informacje. Tomasz Frendzel Plan wykładu: 1. Czym jest system operacyjny, a czym nie jest. 2. Rys historyczny 3. Podstawowe pojęcia związane z systemami operacyjnymi. 4. Wsparcie sprzętowe dla systemów wielozadaniowych, coś co stanowi łącznik pomiędzy tym przedmiotem, a tymi, które związane są z architekturą systemu komputerowego. 5. Z czego składa się system operacyjny i jakie usługi świadczą dane części. 6. Zarządzanie procesami i wszystkimi innymi elementami aktywnymi. 7. Mechanizmy szeregowania zadań 8. Algorytmy szeregowania, synchronizacja procesów, właściwy porządek ich wykonywania i komunikacja między procesami. 9. Zarządzanie pamięcią operacyjną, jak zorganizowana jest pamięć wirtualna i stronicowanie na żądanie itd. 10. Zarządzanie pamięcią masową. Jak strukturalizujemy pamięć dyskową, jak zamieniamy potem te obiekty na bity, jak archiwizujemy pliki w katalogach, jak podejmujemy kroki naprawcze, jak podchodzimy do ochrony itd. 11. Struktury gotowych systemów operacyjnych, jakie cechy mają popularne rodziny systemów operacyjnych. Definicja System operacyjny jest programem, który pośredniczy pomiędzy sprzętem komputerowym a użytkownikiem komputera. Definicja ta jest kontrowersyjna, bo: - użyte jest tutaj słowo program, które sugeruje, że system komputerowy ma charakter taki jak inne oprogramowanie, które może być użyte na komputerze. Inne programowanie będziemy nazywać oprogramowaniem użytkowym. Istota systemu operacyjnego jest inna niż programu UŻYTKOWEGO o czym będzie dalej - definicja ta sugeruje, że użytkownik komputera wchodzi w bezpośredni kontakt z systemem operacyjnym. Natomiast teoria systemów operacyjnych mówi, że nie posiada interfejsu użytkownika, a jedynie interfejs programisty. Zatem system operacyjny to zbiór funkcji, które mogą być wywoływane przez oprogramowanie użytkowe, aby otrzymać dostęp do sprzętu i to jest bliższe prawdzie. Czyli pośrednictwo zachodzi nie między użytkownikiem a sprzętem, tylko między oprogramowaniem użytkowym a sprzętem. Rysunek, który wyobraża tradycyjną architekturę komputerową. (FRENDZEL, JAGODA) CPU RAM DYSK Urządzenia Mysz monitor i jedn. Wejściowe ostka centralna System operacyjny jest nad tym wszystkim, bo to co wyżej to hardware. W systemie są sterowniki do wszystkich tych rzeczy. Sterowniki mają dwie strony, z jednej wiedzą jak posługiwać się konkretnym rodzajem sprzętu, a z drugiej strony wiedzą jak ujednolicić czy też znormalizować nasz interfejs dostępowy do tej klasy sprzętu. Sterownik myszy obsługuje od dołu jeden konkretny model myszy, od góry sterownik obsługuje uogólnione urządzenie sterujące zwane myszą, w ten sposób jak wymieniamy mysz, to wymieniamy

Upload: ngotu

Post on 01-Mar-2019

264 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 1

[email protected], dyżur środa 14-16Będzie mowa o teorii systemów operacyjnych i będą przykłady z konkretnych rozwiązań, będzie wykład oderwany od wszelkich nazw własnych, czyli będzie co innego niż na ćw. Wykład nie będzie miał charakteru narzędziowego. Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach znajdują się tutaj nieświeże informacje. Tomasz Frendzel

Plan wykładu:1. Czym jest system operacyjny, a czym nie jest.2. Rys historyczny3. Podstawowe pojęcia związane z systemami operacyjnymi. 4. Wsparcie sprzętowe dla systemów wielozadaniowych, coś co stanowi łącznik

pomiędzy tym przedmiotem, a tymi, które związane są z architekturą systemu komputerowego.

5. Z czego składa się system operacyjny i jakie usługi świadczą dane części. 6. Zarządzanie procesami i wszystkimi innymi elementami aktywnymi. 7. Mechanizmy szeregowania zadań8. Algorytmy szeregowania, synchronizacja procesów, właściwy porządek ich

wykonywania i komunikacja między procesami. 9. Zarządzanie pamięcią operacyjną, jak zorganizowana jest pamięć wirtualna i

stronicowanie na żądanie itd. 10.Zarządzanie pamięcią masową. Jak strukturalizujemy pamięć dyskową, jak

zamieniamy potem te obiekty na bity, jak archiwizujemy pliki w katalogach, jak podejmujemy kroki naprawcze, jak podchodzimy do ochrony itd.

11.Struktury gotowych systemów operacyjnych, jakie cechy mają popularne rodziny systemów operacyjnych.

DefinicjaSystem operacyjny jest programem, który pośredniczy pomiędzy sprzętem komputerowym a użytkownikiem komputera.

Definicja ta jest kontrowersyjna, bo:- użyte jest tutaj słowo program, które sugeruje, że system komputerowy ma charakter taki jak inne oprogramowanie, które może być użyte na komputerze. Inne programowanie będziemy nazywać oprogramowaniem użytkowym. Istota systemu operacyjnego jest inna niż programu UŻYTKOWEGO o czym będzie dalej- definicja ta sugeruje, że użytkownik komputera wchodzi w bezpośredni kontakt z systemem operacyjnym. Natomiast teoria systemów operacyjnych mówi, że nie posiada interfejsu użytkownika, a jedynie interfejs programisty. Zatem system operacyjny to zbiór funkcji, które mogą być wywoływane przez oprogramowanie użytkowe, aby otrzymać dostęp do sprzętu i to jest bliższe prawdzie. Czyli pośrednictwo zachodzi nie między użytkownikiem a sprzętem, tylko między oprogramowaniem użytkowym a sprzętem.

Rysunek, który wyobraża tradycyjną architekturę komputerową. (FRENDZEL, JAGODA)

CPU RAM DYSK Urządzenia Mysz monitor i jedn. Wejściowe ostka centralna

System operacyjny jest nad tym wszystkim, bo to co wyżej to hardware. W systemie są sterowniki do wszystkich tych rzeczy. Sterowniki mają dwie strony, z jednej wiedzą jak posługiwać się konkretnym rodzajem sprzętu, a z drugiej strony wiedzą jak ujednolicić czy też znormalizować nasz interfejs dostępowy do tej klasy sprzętu. Sterownik myszy obsługuje od dołu jeden konkretny model myszy, od góry sterownik obsługuje uogólnione urządzenie sterujące zwane myszą, w ten sposób jak wymieniamy mysz, to wymieniamy

Page 2: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 2

tylko sterownik a nie cały system operacyjny. Sterownik ma za zadanie przekształcić ogólne wezwania urządzenia sterującego na wezwania do konkretnej myszy. System operacyjny nie musi dostosowywać się do urządzenia danej klasy, choć jest problem, gdy się pojawiają urządzenia nowej klasy.

Źródło pochodzenia sterowników – sterowniki są częścią systemu operacyjnego, ale sensowniejszym miejscem ich wytwarzania jest miejsce, w którym wytwarza się sprzęt, specyfikacja tego sterownika może dać konkurencji informacje o wewnętrznej budowie tego sprzętu dlatego raczej producenci sprzętu trzymają pod kontrolą jak są zbudowane te sterowniki, a piszą go dobrze bo wiedzą, czego system operacyjny oczekuje od tego sterownika. Jednym z podstawowych profitów używania tej architektury jest to, że odpowiedzialność spoczywa na oprogramowaniu wysokiego stopnia zaufania, czyli na systemie operacyjnym, a nie na niewiadomego pochodzenia aplikacjach. Nie bardzo wiemy, co się dzieje w samym systemie operacyjnym, a góra tego systemu to ta warstwa użytkownika to Application Programming Interface czyli API - jest to specyfikacja zbioru funkcji wraz z opisem ich działania, która jest dostarczona programistom warstwy użytkowej dla zaspokojenia ich potrzeb, jeśli chodzi o udostępnianie zasobów komputera. System operacyjny to ten interfejs plus jego implementacja w dolnych warstwach.

Unix jest źródłem systemów operacyjnych i w tym systemie jest taka cezura pomiędzy oprogramowaniem na poziomie jądra - uprzywilejowanym a oprogramowaniem na poziomie użytkownika. Ta cezura w innych systemach jest bardziej rozmyta np. w systemie NT, np. serwery użytkowe mogą pracować w zależności od potrzeb w obu trybach.

A nad cezurą mamy np. edytor tekstu.Współpraca między aplikacją użytkową a resztą architektury komputerowej na przykładzie edytora tekstu. Inny przykład to aplikacja biznesowa z biblioteką wsparcia i wtedy tylko ta aplikacja ma interfejs dla użytkownika, biblioteka już go nie ma bo biblioteka to zbiór funkcji, które mogą być wywoływane przez aplikację. Ta aplikacja może pracować z silnikiem bazodanowym, który korzysta z biblioteki wsparcia, ale też z odwołań do funkcji systemu operacyjnego. Silniki bazodanowe są mało efektywne i ślad ich działalności jest tylko w liście procesów, ich działanie objawia się w sposób pośredni.

Dalej nad naszą cezurą w trybie użytkownika jest menager programów czyli coś co pozwala nam zarządzać uruchamianymi programami i pozwala to wizualizować. Jest to program tej samej klasy co edytor testu, aplikacja biznesowa itd. Choć może to być coś prymitywnego. Następnie obok tego managera może być gra komputerowa, która też się kontaktuje z systemem operacyjnym. Czyli system jest takim filtrem, który pośredniczy w odwoływaniu się aplikacji do sprzętu.

Rysunek ten budzi kontrowersje:- czy na pewno istnieje coś takiego jak sterownik procesora czy sterownik pamięcią operacyjna? Odp. Nie może istnieć, bo sam sterownik musiałby z tej pamięci i procesora korzystać, a przecież ciężko sobie wyobrazić tłumacza, który zajmuje się odwołaniami natury stricte aplikacyjnej do tych dwóch elementów. Istnieją warstwy które symulują procesor i działa tak naprawdę w trybie użytkownika patrz Java, ale to później,. Wystarczy powiedzieć, że te elementy jak CPU i pamięć operacyjna mają charakter umowny. Przykład z Windows : biblioteka HAL (Hardware Abstraction Layer) to biblioteka dynamiczna, początkowo system Windows nt był przeznaczony na wiele platform komputerowych i z czasów tej przenośności pochodzi owa biblioteka, która normalizowała strategie dostępu do trybów procesora, przerwań oraz trybów pracy pamięci operacyjnej w różnych środowiskach. Zmiana trybów procesora z uprzywilejowanego na nieuprzywilejowany w różnych procesorach. Obecnie ta biblioteka jest niepotrzebna, ale jeśli ją usuniemy to Windows nie ruszy, wiec coś tam jest, ale nie wiadomo co, można powiedzieć, że to sterownik procesora i pamięci.

Page 3: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 3

Czy niektóre systemy pozwalają na to by traktować system nie jako obowiązkowego pośrednika, tylko jako opcjonalnego pośrednika dostępu do sprzętu, czyli pytamy czy istnieją możliwości obejścia systemu operacyjnego? Np. system Dos niby był operacyjny, ale nie ma zgodności między nim a naszym rysunkiem. Tam aplikacja mogła wywołać funkcje systemu DOS by sobie zapewnić dostęp do urządzenia wejścia wyjścia, ale mogła dostać się do tych urządzeń też bez systemu. Pozwalano na to dlatego, bo nie było motywacji by robić inaczej, bo Dos był systemem jednoprogramowym, czyli w jednej chwili pracował w systemie tylko jedne program, zatem awaria tego programu skutkująca dysfunkcja całego otoczenia odnosi się tylko do tego programu i wtedy się restartowało komputer i w ten sposób restartowaliśmy aplikacje ,a że razem z systemem to trudno. Zmieniła się sytuacja gdy doszliśmy do tego, że mamy wiele pracujących programów w systemie operacyjnym, tym bardziej, że ten system może być systemem wielodostępnym i jeszcze świadczyć na zewnątrz również usługi - wtedy gdy zawiesi nam się notatnik to nie chcemy naciskać resetu. Sprawa stabilności na poziomie źle napisanych aplikacji robi się istotna gdy wprowadzamy wieloprogramowość.

Dlatego trzeba kontrolować sposób korzystania z zasobów, korzystania z naszego komputera przez aplikacje i to właśnie robi system operacyjny, by awaria aplikacji była awarią tylko tej jednej aplikacji, a nie całego zbioru programów. To oczywiście jest teoria. Każda aplikacja powinna się czuć tak, jakby miała wirtualny komputer z wirtualnymi zasobami udostępniony tylko jej, część może być niedostępna, bo ważniejszy element programistyczny może tego wymagać i to jest lepsze niż doprowadzenie do kompletnej dysfunkcji całego systemu. Jednak wtedy podniesienie poziomu stabilności ma też swój koszt. Kosztem jest tutaj wydajność, jeśli każda najmniejsza operacja musi być filtrowana przez wiele warstw systemu operacyjnego który wykonuje wiele porównań, ocenia i szacuje bieżący stan naszej architektury to w przypadku gwałtownych odwołań do danego komponentu będziemy czuć duży spadek wydajności. To nie dotyczy wszystkich aplikacji ani wszystkich rodzajów sprzętów. Niektóre systemy mają lekkie obejmy systemu operacyjnego np. direct x pozwala na dostęp bezpośredni. Gdyby tych obejm nie było, to byśmy grali tylko w szachy, podobnie bez tego nie dało by się nadążyć za filmami akcji. Np. odtwarzacz multimedialny i prtscr wtedy dostaniemy czarny prostokącik, to taki paradoks.

Ponadto pewnie rzadko mamy do czynienia z sytuacjami które są oznaką kompletnej niestabilności systemu operacyjnego, mówimy głownie o Windowsie. Ale jak już idą w krzaki to zdarza się to najczęściej wtedy, gdy mamy dysfunkcujący sprzęt lub gdy mamy sterowniki, które nie są do końca sprawdzone, lub pochodzą z niepewnych źródeł , ale gdy oba te warunki nie są spełnione, tylko mamy cudownie, to zawieszenie zdarzy się wtedy gdy nie korzystamy z klasycznych metod walidacyjnych systemu operacyjnego tylko robimy to przez lekkie obejmy czyli mówimy tutaj o grach komputerowych lub odtwarzaczach multimedialnych, te rzeczy potrafią doprowadzić nasz system do stanu kompletnej dysfunkcji z powodu bardzo ekspansywnej utylizacji sprzętu.

Zatem podstawowym zadaniem systemu operacyjnego jest utrzymywanie stabilności poprzez limitowanie dostępu do zasobów sprzętowych. Ta idea by każda aplikacja czułą się w systemie tak jakby była w systemie wirtualnym jest dobre ;)

System wsadowy

Z Wikipedii:System wsadowy (ang. batch system) - to komputerowy system operacyjny, który na stałe rezyduje w pamięci operacyjnej. System ten najczęściej po wykonaniu jednego zadania przekazuje dane wyjściowe kolejnemu zadaniu gdzie te dane służą jako dane wejściowe.Cechy:- Można wykonywać tylko jedno zadanie (brak wielozadaniowości)- Brak bezpośredniego nadzoru przez użytkownika

Page 4: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 4

Koniec lat 50tych, początek 60tych. By się cofnąć w ten punkt w czasie należy sobie uświadomić rzeczy, które z punktu widzenia człowieka dzisiejszego są dość niesamowite:- komputery były bardzo rzadkie i bardzo drogie, dostępne dla nielicznych- użytkownik komputera była to osoba ze wszech miar świadoma tego co robi, nie odtwarzająca danych gestów, tylko programista, ktoś kto miał do wykonania pewne zadanie związane z obliczeniami lub przetwarzaniem dużej ilości danych, przypomnijmy, że programy były wtedy pisane na taśmach / kartach perforowanych.

Szybko nastąpiło przejście na system wsadowy. Gdybyśmy wynajmowali komputer na godziny, to często byśmy mieli do czynienia z marnotrawieniem mocy obliczeniowej, bo nie byliśmy w stanie oszacować tego ile nam zajmie nasza praca, chociażby często program się nagle wysypywał, wiec nie mogliśmy zdążyć w wyznaczonym czasie wykonać nasze obliczenia, a program by poprawić trzeba się z nim przespać ;). Może też być w drugą stronę – program działał dłużej niż przewidywaliśmy…No i w nocy komp nie pracował… ;)

Zatem bardziej optymalnym układem byłby układ z operatorem, czyli nie wchodzimy w bezpośredni kontakt z kompem, tylko ktoś odbiera nasze dzieło i to on robi dla nas czynności typu określenie czasu wykonania, uruchomienie naszego programu itp. Kolejnym etapem było zastąpienie operatora przez mechanizm automatyczny. Programista określał reżimy czasowe, priorytety itp. I tak opakowany program był dostarczany mechanizmowi, który go odpowiednio kolejkował. Po wprowadzeniu tych mechanizmów nasze kompy przestały potrzebować pośrednika i zaczęły same sterować zadaniami.

System Job Control Language był pierwszym takim mechanizmem, długo funkcjonował bo koło 20 lat na tych wielkich komputerach, współpracował z wieloma urządzeniami pamięci masowej na wejściu. Nie musieliśmy się martwić o autoryzacje, nasze zadania były wykonywane w nocy, zadania ważniejsze były wykonywane przed tymi mniej ważnymi, rozsądna gospodarka itp. To był pierwszy prototyp systemu operacyjnego, bo zarządzał wykonywaniem wielu programów dla wielu użytkowników.

Czy system wsadowy żyje we współczesnych rozwiązaniach?Można udzielić tu odpowiedzi twierdzącej. Reszty nie zdążyłam zanotować…

Kolejna technologia to przetwarzanie satelitarne (praca pośrednia) ale by do tego dojść trzeba sobie uświadomić, że statystycznie najczęstszym rodzajem zadań dla komputerów to było co innego niż dziś... Obecnie oprogramowanie jest nastawione silnie na interakcje z użytkownikiem, a wtedy oprogramowanie było dużo mniej efektowne w działaniu, większość programów składała się z 3 rozłącznych części – wczytania, przetworzenia i wyprowadzenia danych na wyjście. Wejście i wyjście to były fazy niskie, a obliczenia to faza wysoka. (patrz zdjęcia). Zauważmy, że zwykle nie dajemy komputerowi trudnych rzeczy tylko proste o dużej ilości danych, wiec środkowa część związana z obliczeniami była najdroższa, ale miała mały udział. Komputery liczą po prostu szybciej, procesory i pamięć operacyjna były bardzo drogie. Zatem wszystko było zdeterminowane przez wielkość danych wejściowych i wyjściowych, a nie przez obliczenia same w sobie.

Pytanie zatem czy można cały ciąg czynności wykonać szybciej? Ano jeśli założymy sobie, że wejście realizowane dla programu może następować równolegle z obliczeniami wykonywanymi przez inny program. Nie kompresujemy kapelusików (fragmenty wykresu patrz foty) tylko przesuwamy kapelusiki, chcemy zaczynać je w końcu poprzedniego. Wejścia mogą być współbieżne, ale wtedy trzeba by było część danych tymczasowo przechowywać,. Współbieżne obliczenia to już kłopot, bo wymagają więcej niż jednego w tym samym czasie pracującego procesora. Jednak nawet

Page 5: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 5

ta współbieżność wejść wymagała zmian w dotychczasowej architekturze komputera. Jeśli dane miałyby być wczytywane równolegle z obliczeniami, to przy wczytywaniu danych nie mógł pracować główny procesor, bo był zajęty obliczeniami, czyli potrzebna była jednostka pomocnicza która potem miała informować główny procesor, że już skończyła dane wczytywać.

Komputer główny zamawia w kompie satelitarnym wykonanie dla niego operacji wejściowej. To zamówienie jest wykonywane przez spięcie elektroniczne (rzadko) albo zapisanie pewnej informacji w buforze uwspólnionym (yyy, jest taki wyraz, prawda?)między pamięcią komputera głównego i satelitarnego, na co on tylko czeka. Po dokonaniu tego zamówienia komp satelitarny komunikuje się z urządzeniem wejściowym, które rozpoczyna wypełnianie tego uwspólnionego bufora danymi. W tym czasie komp główny robi co chce np. wykonuje obliczenia dla innego procesu.

Pytanie jest więc w jaki sposób dowie się, że zamówiona operacja wejściowa uległazakończeniu? Otóż nie czeka na zakończenie tej operacji, bo nie robiłby wtedy niczego poza czekaniem, czyli musi zostać poinformowany o zakończeniu tej operacji bez względu na to co robił. Jak ten sygnał elektroniczny był, to przestawał wykonywać to co robił i się brał za co innego – mamy linię przerwań, a potem wracał z niezmienionymi stanami do tego co robił wcześniej .Dzięki temu komputer główny mógł wiedzieć, że operacja wczytywania info wejścia wyjścia została zakończona. To komp satelitarny DOZOROWAŁ pilnowanie wejścia wyjścia, a komp główny rezygnował z tego. Sterowanie asynchroniczne. Możemy przyłączyć jeszcze jedno urządzenie wejścia, urządzenia wyjścia itp., wiec mogły być wykonywane działania współbieżne z wejściem i wyjściem i to jeszcze na wielu urządzeniach.

Czy coś takiego funkcjonuje teraz?Przecież nikt nie ma do swojego wielkiego kompa i dołączonych do niego wielu małych… Ale ta architektura funkcjonuje dziś, tyle że na innym poziomie – jest zamontowane w pudełkach z naszymi komputerami. Każde urządzenia mają swoje kontrolery, które przekazują info do procesora głównego, który nie czeka na przerwanie, ono się nagle pojawia i zostaje ten fakt obsłużony w nieco inny sposób. Tyle że są to komputery wbudowane wykonujące wciąż ten sam kod który pozwala na skuteczną komunikację z jądrem urządzenia wejściowo wyjściowego.

To był zaczyn technologii wieloprogramowości co przekształciło się potem w wielozadaniowość. Jednoprogramowy system DOS uruchamiał jedno zadnie naraz, a mimo wszystko korzystał z mechanizmu przerwań przy obsłudze urządzeń wejścia wyjścia, czyli to czekanie już wtedy się nie opłacało.

Kolejna technika, która zaczęła się pojawiać w systemach preunixowych to technika buforowania danych, która zaczęła mieć miejsce gdy następował spadek cen pamięci operacyjnej i tej pamięci było więcej niż było potrzebne do wykonywanych zadań, czyli był taki problem nadmiaru. Stąd ta koncepcja buforowania danych.

Powstaje pytanie: jeżeli z urządzenia wejściowego odczytaliśmy dane, to po konsumpcji danych przez program te dane mają być natychmiast usunięte z pamięci? Dla pedantycznych systemów operacyjnych może tak, ale… Możemy przechowywać wczytane dane póki nam nie zabraknie pamięci, wtedy je usuniemy. Może też być urządzenie które dostarcza nam dane w sposób sekwencyjny. Może się okazać, że bardziej nam się opłaca dostarczenie w jednym czasie większej ilości danych niż zamówione, np wiecej niż 1 bajt z dysku, powiedzmy blok danych, bo istnieje wysokie p-stwo, że użytkownik za chwile poprosi o drugi bajt, więc zamiast z dysku dostanie on go z bufora, który wypełniliśmy sobie zawczasu, Ograniczymy liczbę kontaktów z dyskiem a zwiększymy z pamięcią operacyjną. Po stronie wyjściowej możemy postępować w podobny sposób. Faktycznego zapisu możemy dokonywać wtedy, gdy bufor wymaga

Page 6: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 6

zajęcia przez inne dane. Dzięki tej technice jest wszystko jedno czy zapiszemy 1000razy po 1 bajcie, czy jednorazowo 1000bajtów i tak obie te rzeczy będą w pamięci operacyjnej.

Czy są jakieś zagrożenia związane z buforowaniem? Z zajmowaniem pamięci operacyjnej tymczasowymi danymi?Są - od tego czasu zaczęła istnieć potrzeba ładnego wyłączania naszych systemów, bo nagłe wyłączenie naszego systemu mogło spowodować, że dane które uważaliśmy, że zapisały się już, były tak naprawdę zapisane w pamięci ulotnej… Stąd mechanizmy podtrzymywania energii do czasu awaryjnego zrzucenia danych z bufora na dysk. W przypadku dzisiejszych systemów unixowych trudno mówić byśmy mieli jakąś wolną pamięć operacyjną, ten stan się utrzymuje, bo wszystkie nieprzydzielone procesom fragmenty pamięci operacyjnej to bufory gromadzące info z urządzeń wejścia wyjścia. Im tych buforów więcej tym optymalność działania systemu na linii kontaktu z urządzeniami wejścia wyjścia jest wyższa.

Buforowanie może tez się odbywać w szybkiej pamięci masowej Spooling –kolejkowanie to rodzaj pośrednictwa o charakterze stałym, dane zapamiętywane są w ten sposób, że przeżywają wyłączenie systemu. Np. system drukowania – jeśli mamy duży zapas pamięci na dysku, to może procesy zamiast drukować na drukarce stworzą zadania do drukowania na dysku, z którego w pewnym odpowiednim optymalnym porządku będą one pobierane i kierowane do samego wydruku, więc czas wykonania operacji wyjściowych pozornie się wyredukuje, bo faktyczne wydruki pójdą w tym samym tempie. W przypadku wejścia też można sobie to wyobrazić, ale jest trudno, możemy zapisywać dane z taśm perforowanych na dysku i urządzenia wejściowe mają pracować cały czas nad wprowadzaniem danych, nie ma zatorów i skuteczny będzie podział zadań miedzy urządzeniami wejściowymi.

To buforowanie przez dysk jest obecnie w stanie zaniku i ma silniejsze znaczenie jako punkt gromadzenia innego rodzaju informacji ale w nieco innym charakterze otóż ciekawa jest analiza pewnego katalogu, który w systemach unikowych jest przeznaczony na kolejkowanie tj. var/spool. Będzie tam wiele fajnych kolejek np. At – podsystem, który umożliwia wykonywanie zadań w określonym przez użytkownika czasie. Kolejka zadań cyklicznych i inne tez tam są. Jest też katalog lpd i katalog mail – gromadzi przychodzącą pocztę elektroniczną. Poczta elektroniczna to podsystem, który wymaga buforowania przez dysk, bo nie wiadomo kiedy użytkownik tą pocztę odbierze. Inna kolejka to mqueue - kolejka poczty wychodzącej – może chwilowo nie być możliwe uzyskanie połączenia między systemami serwerowymi i musimy na niego poczekać.

Jak już mamy pulę zadań do wykonania, jak już jest zrównoleglenie operacji wejścia wyjścia i obliczeń to chcemy to zebrać w jedną koncepcję i pojawiła się ona w unixie -koncepcja wieloprogramowości której fundamentami wtedy były:

1. Jednocześnie w pamięci operacyjnej komputera znajduje się wiele uruchomionych programów, procesów czy zadań (w zależności od nomenklatury)

2. Każde uruchomione zadanie wykonywane jest w naprzemiennym cyklu: obliczenia – czyli faza procesora oraz faza wejścia lub wyjścia.

3. Z chwilą kiedy wykonywany program zrzeka się procesora przechodząc do fazy wejścia wyjścia, procesor przekazywany jest do innego procesu.

Ad 1.Sprawa oczywista, choć budowa takiego systemu, który umożliwia wprowadzenie wielu programów jednocześnie do pamięci operacyjnej nie jest prosta o czym za chwile.

Ad.2.

Page 7: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 7

Powstaje pytanie czy rzeczywiście każdy program uruchamiany u nas na kompie wykonuje się w owej naprzemiennej fazie? Są różne klasy oprogramowania, różne sposoby zachowań i różna obciążalność naszego systemu różnymi typami zadań.

Kiedy nasz komp angażuje procesor w wykonywanie czynności dla nas, a kiedy jest mu niepotrzebny? Weźmy program – wprowadź x, wprowadź y, wyprowadź x+y. Z punktu widzenia programisty to program obliczeniowy, bo dodaje do siebie dwie liczby, więc wydaje się ze potrzebuje mocy obliczeniowej no i potrzebuje, ale ona jest marnotrawiona na…

- Najpierw czynności wstępne typu inicjalizacja wejść, wyjść, przydzielanie pamięci itp.- Potem mamy zamówienie operacji wejścia pierwszego łańcucha znaków z klawiatury, które potem są interpretowane jako liczby, co robi funkcja biblioteczna typu scanf, która interpretuje łańcuch znaków jako określony typ danych binarnych. - Potem faza niska zależna od naszego szybkiego pisania na klawiaturze ;) Wtedy komp jest na wczasach, bo przekazał już wszystko do systemu operacyjnego- Potem mamy obliczenia, czyli ciało funkcji scanf, która nasze łańcuchy doprowadzi do postaci binarnej i zapisze w jakimś miejscu w pamięci- Dalej zamówienie odczytu drugiego łańcucha- Odczyt drugiego łańcucha – komp na urlopie, bo to system operacyjnym wprowadza- Interpretacja drugiego łańcucha- Jądro programu czyli z=x+y, to jest malutkie, bo np. scanf się znacznie bardziej natrudził niż procesor dodając dwie liczby- Potem chcemy printf, który rozpoczyna się od tego, że binarna postać wyniku naszego działania jest uogólniona do zrozumiałej postaci- Wyjście związane z transmisją szeregową czy sieciową, program na urlopie, czynności końcowe.

Widzimy, że te dwie fazy naszego programu są dramatycznie dłuższe niż cała niby istotna reszta. Taki program nie angażuje procesora naszej maszyny w żaden sposób.

Kiedy angażuje procesor edytor tekstu?Gdy użytkownik wciśnie przycisk…Wtedy on duuużo robi, to musi ładnie wyglądać na ekranie, ewentualnie szuka od razu w słowniku czy taki wyraz jest itp. Podobnie w sumie pracuje odtwarzacz multimedialny – rozważmy taki gdzie strumień jest słabo i taki gdzie jest mocno skompresowany. Odtwarzacz bierze fragment strumienia i doprowadza go do postaci gotowej do wyjścia (np. do gry) – dekompresja jest dłuższa, gdy strumień bardziej skompresowany. Nie widać dekompresji, nie staje nam odtwarzanie, a to dlatego bo ono jest robione w trakcie wyświetlania poprzednio zdekompresowanej wartości. Gdy ta dekompresja trwa dłużej to się film rwie ;) Z kompresją danych jest inaczej, ta kompresja nie musi być w czasie rzeczywistym.

Proces systemowy bezczynny – gdy procesor nic nie robi to jest to robi…Zlicza nic nie robienie i to jest wymowny czas naszej utylizacji cokolwiek to znaczy…

3 podstawowe problemy1. Bardzo poważny – współistnienie w pamięci operacyjnej wielu programów wymaga zaawansowanych metod zarządzania pamięcią operacyjną. Jeżeli mamy do czynienia z systemem jednoprogramowym to np. możemy założyć, że każdy program będzie zajmował pamięć od jakiegoś systemu w górę, a jak mamy system wieloprogramowy to to co jest dziś nie musi oznaczać tego co będzie jutro, bo jednego dnia mogę uruchomić Worda i Excela, a innego dnia Excela i Worda czyli inna sytuacja, to nie jest wszystko jedno. Programy muszą więc móc się swobodnie przemieszczać się po pamięci operacyjnej.

2. Jeżeli jeden proces zrzeka się procesora to sterowanie przekazywane jest do innego procesu - pytanie do którego? To nie jest wszystko jedno choć musimy je wszystkie

Page 8: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 8

zrobić. Możemy doprowadzić do sytuacji, w której jedne procesy będą dostawały za mało mocy obliczeniowej, czyli będą głodzone, albo do takiej, że niektóre procesy w ogóle przestaną się wykonywać, więc musimy ułożyć strategię udziału procesora do gotowych do wykonania zadań i o tym będziemy dużo mówić.

3. Jeżeli w pamięć operacyjnej rezyduje wiele procesów, to nie mogą one wchodzić ze sobą w konflikty, np. w konflikty zwiane ze wzajemnym uszkadzaniem sobie przestrzeni adresowych, czyli muszą tak pracować, jakby były uruchamiane na osobnym komputerze każdy, te programy mogą wymieniać między sobą dane ale pod kontrolą.

Wielozadaniowość – coś co nie pozwala żadnemu procesowi zawłaszczyć mocy procesora.

Po dsumowując, system wsadowy realizuje swoje zadania poprzez automatyczna realizacje kolejki zadań przygotowanych wraz z opisem ich wykonania i warunków pracy.

System wielozadaniowy różni się od wieloprogramowego tym, że zachodzi w nim podział czasu, procesor jest udostępniany procesowi, ale z limitem czasu wykonania. Jeżeli limit ten nie zostaje przekroczony, zachowanie obu typów systemu jest jednakowe. W momencie jednak, gdy proces nie chce oddać procesora przez dłuższy czas, jest on pozbawiany procesora na siłę (następuje wywłaszczenie czasowe).

Wyobraźmy sobie, że mamy do czynienia z systemem opartym na jednym procesorze i wykonujemy w nim jakieś zadanie obliczeniowe, które wymaga 100%utylizacji procesora. Jeśli są to same obliczenia, to po upływie pewnego kwantu czasu nastąpi wywłaszczenie i oddanie procesora do innego procesu. Zatem jeśli w systemie wielozadaniowym są uruchomione dwa takie zadania przy jednym procesorze, to pewien odcinek czasu procesor pracuje nad jednym zadaniem, potem mamy wywłaszczenie czasowe, i pracuje jakiś kawałek czasu nad drugim zadaniem i potem znów wraca itp. Jeśli ten limit czasu, ta częstotliwość wywłaszczenia jest krótka, to użytkownik ma wrażenie, że oba te zadania są posuwane do przodu, tyle że dwukrotnie wolniej niż by to miało miejsce, gdyby były same na tym komputerze.„Każdy z tych procesów posuwa swoją logię do przodu tyle, że dwukrotnie wolniej niż gdyby pracował sam”

Można puścić teoretycznie dowolną liczbę procesów. Czyli jakbyśmy mieli n procesorów o mocy 1/n tego procesora wejściowego. Oczywiście wywłaszczanie czasowe kosztują, spadek mocy jest. Jednak w sumie nasz komputer jest w stanie wykonać symulowane równoległe obliczenia poprzez przełączanie czasu. Jeśli się zastanowimy jak to zrealizować, to się okaże, że to proste, wystarczy mieć taki czasomierz, nastawiamy pewien kwant czasu i po nim następuje przerwanie, to wystarczy do wielozadaniowości. W Windows wersja 3 jednak tego nie było, choć byłoby to wykonalne. Wielozadaniowość dla zwykłej stacji roboczej nie jest niezbędna, chociażby dlatego, bo człowiek nie jest wielozadaniowy, sama interakcja człowieka z programem nie jest wielozadaniowa. Poza tym w sumie użytkownicy często nie widzą, że coś wysysa soki z ich komputera.

Wielozadaniowość pojawiła się pod koniec lat 60tych razem z Multix, który potem ewoluował w Unix, który był wielozadaniowy od początku, czyli Microsoft nie odkrył tego wraz z systemem windows95.

Systemy czasu rzeczywistegoTo system, który można zdefiniować tak – reakcja na bodziec zewnętrzny jest ściśle ograniczona czasowo. Koncepcja wielozadaniowości i koncepcja reżimu czasu rzeczywistego są w pewnym sensie wzajemnie sprzeczne, bo cechą systemu wielozadaniowego jest to, że nigdy nie jesteśmy w stanie stwierdzić, jak długo będzie się wykonywało zadanie, które my zlecimy, bo może się okazać, że system jest na tyle obciążony, że nasze zadanie będzie się wykonywało wielokrotnie wolniej niż gdyby obciążony nie był. Zatem tutaj ograniczenia czasowe są dość trudne do spełnienia. Część

Page 9: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 9

systemów wielooperacyjnych jest reklamowana jako niby systemy jednocześnie wielozadaniowe i jednocześnie systemy czasu rzeczywistego. W Większości wypadków tak naprawdę (w qnx, czy Windows NT) jest system priorytetów odpowiednio ułożony, pewne klasy procesów zawsze wywłaszczają inne klasy procesów, czyli zrzekamy się wielozadaniowości w momencie, gdy nasze zadanie musi być zrealizowane w danym czasie. Przykład Robocika budującego autka ;)

Na tym koniec historycznych trendów rozwojów systemów operacyjnych i pojęć wstępnych.

Wsparcie sprzętowe dla systemów wieloprogramowych i wielozadaniowych

Nie będziemy mówili dokładnie o tym jak system operacyjny powinien być zbudowany tylko o tych wąskich gardłach, które sprawią, że implementacja wielozadaniowości czy wieloprogramowości może być niemożliwe. Pierwsze co to :

PrzerwaniaMusimy umożliwić naszemu procesowi zrzeknięcie się procesora w danym momencie, czyli jak zrealizować zakończenie oczekiwanie na koniec operacji wejścia – wyjścia. Podstawą do rozważań będzie model, który nazywa się

Aktywne czekanie (wirująca blokada)W pseudokodzie możemy wyobrazić ją sobie tak:

Zamówienie_operacji_wejsciawyjscia();While(znacznik_konca_operacji==w_toku);/* tu możemy się zająć konsumpcją danych*/

To taki specyficzny wzorzec projektowy i pomyślmy jaki poziom utylizacji on generuje. Uświadomimy sobie, że ta pętla generuje 100% operację obliczeniową, że nie ma różnicy między tą pętlą, a for(;;), tyle że nasza pętla ma sens, to istota oczekiwania, a for(;;) tego sensu nie ma. Nasza pętla skończy się bezpośrednio po tym jak urządzenie wejścia wyjścia zakończy swoją pracę, ale koszt takiej operacji jest bardzo duży. Jeśli system jest wyposażony w wywłaszczenia czasowe to się niby nie musimy tym przejmować, ale to kręcenie się w pętli jest kompletnie nieproduktywne, bo nawet jeśli wywłaszczenia czasowe będą, to po co ten program ma spowalniać inne operacje. A bez wywłaszczenia to już w ogóle nie ma sensu, to taka skończona nieskończona pętla. Możemy zmieniać tempo testowania znacznika końca operacji, zamontować jakiś mechanizm wstrzymywania czasowego, byśmy się jakby wolniej kręcili w kółko, czyli po czasie trochę się zrzekamy, potem znów testujemy, znów czekamy trochę itp. Utylizacja więc spada, bo w czasie trochę wykonujemy inny kod, inne operacje. Ale utylizacja ta nie spada do zera, ponadto zaczynają się pojawiać problemy związane z niewykorzystywaniem do końca możliwej prędkości urządzenia wejścia wyjścia, bo jeśli to urządzenie zakończyło pracę po czasie 1/10 ‘trochę’ to my to zauważymy dopiero po czasie ‘trochę’, czyli straciliśmy 90% jego prędkości przetwarzania. Im bardziej zwiększamy tempo, czyli zmniejszamy ‘trochę’, tym bardziej przypomina to wirującą blokadę. Dlatego załatwiamy sprawę przez

Czekanie bierne (asynchroniczne) Zamawiamy operacje wejścia wyjścia i natychmiast po tym zrzekamy się procesora, następuje samouśpienie.

Zamowienie_operacji_wejsciawyjscia();Usypianie_sie(); // wstrzymuj_na(WIECZNOSC)

Budzenie odbywa się taką metodą, że w przerwaniu generowanym po realizacji zamówienia nastąpi procedura budzenia procesu. Natychmiast po zakończeniu prac przez

Page 10: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 10

urządzenie wejścia wyjścia proces zostanie wznowiony, ale w czasie oczekiwania na dane proces nie będzie angażował procesora. To jest podobne do czekania na zmianę świateł, możemy czekać aktywnie – patrzeć się bardzo usilnie na nasz sygnalizator, jest ono męczące, próbkowanie wygląda w ten sposób, że od czasu do czasu odrywamy wzrok od innych zajęć i patrzymy, czy światło nie zmieniło się na zielone. A najbardziej sensowne wbrew pozorom byłoby czekanie, aż ktoś da nam sygnał, że światła się zmieniły, najlepiej klaksonem a nie powodowaniem stłuczki ;)

Systemy wyposażone w przerwaniaZ reguły jedna linia przerwań to za mało, by obsłużyć wszystkie urządzenia wejścia wyjścia, procesy. Da się inaczej – karty sieciowe wieloportowe. Kwestia naszej kontroli nad przerwaniami – jeśli byśmy pozwolili wykonywać przerwania bez żadnej kontroli programistycznej, to byśmy mieli kłopoty w systemach czasu rzeczywistego, bo generowane przerwania powodowałyby duże obciążenia czasowe, dlatego czasami musimy maskować – wyłączać całe grupy przerwań. Przerwania mogą być też kolejkowane do momentu aż będą warunki, by je skonsumować. System musi też być chroniony przed kaskadą przerwań. Suport ze strony procesora obsługi przerwań… Jeśli chcemy zrealizować wielozadaniowość to potrzebujemy czasomierz – coś co pozwoli nam dokonać wywłaszczenia w momencie przekroczenia limitu czasowego, takie urządzenie generujące przerwania czasowe.

Procedura obsługi przerwania – wtedy wykonywany jest tak naprawdę bardzo mały kod. Najczęstszą akcją podejmowaną jest akcja: znajdź proces, który zamówił operacje wejścia wyjścia, która wygenerowała to przerwanie i druga faza – zmień stan tego procesu (zapal bit gotowości).

Pierwszy poziom niezbędnego wsparcia sprzętowego:Bezpośredni dostęp do pamięci DMA (Direct Memory Access)To technologia w której urządzenia we-wy są na tyle inteligentne, że umieją wynegocjować z procesorem miejsce, w którym będą buforowane dane, zapisywane są bezpośrednio do przestrzeni adresowej procesu, a nie do jakiegoś bufora i dopiero z niego potem kopiowane. Wielkość tego bufora może być swobodnie modyfikowana, a jak mamy bufor ustalony to wielkość jego jest stała. DMA pokazuje korzyści, gdy urządzenie we-wy jest bardzo szybkie i wymiania bardzo dużo danych z pamięcią naszego komputera, wtedy DMA powoduje ładny przyrost prędkości. Wykorzystywane w dyskach twardych, w karcie graficznej, która wymienia przecież bardzo szybko i duże porcje danych z pamięcią operacyjną. Ale technika DMA wymaga zainwestowania w stopień skomplikowania naszego systemu operacyjnego chociażby dlatego, bo skoro urządzenie we-wy może dość swobodnie negocjować ten bufor, to musimy oszczędzać go, by nie uległ przemieszczeniu, bo na systemach opartych na pamięci wirtualnej, to będzie tak, że położenie tego będzie się zmieniać, a wypada, by urządzenie we-wy nie czytało danych z miejsca które ma zupełnie inne już przeznaczenie.

Druga rzecz to:Dualny tryb pracyNa liście zadań do wykonania przez procesor są zadania potencjalnie niebezpieczne, tzn. na liście rozkazów procesora Intela znajduje się rozkaz Halt, który powoduje zatrzymanie procesora. Wyobraźmy więc sobie, że rozkaz ten jest swobodnie możliwy do wykonania przez dowolnego użytkownika. Jeśli tak użytkownik zrobi w systemie wieloprogramowym, lub co gorsza wielodostępnym, czy świadczącym usługi sieciowe, to sytuacja będzie taka, że zatrzymamy procesor, czyli zatrzymamy wszystkie inne programy, które pracowały w nim równolegle. Systemy się bronią przed wykonywaniem nielegalnych instrukcji. Halt jest potrzebny, bo jakąś procedurę zamknięcia systemu trzeba czasami wykonać i wtedy ten procesor trzeba wyłączyć, ale nie możemy dopuścić, by nasi użytkownicy mogli ten halt wykonać, bo on im się będzie niechcąco wymuskiwał. Dlatego wprowadzono dualny tryb pracy procesora – procesor ma dwie listy rozkazów, jedna to lista trybu uprzywilejowanego i podzbiór – rozkazy trybu nieuprzywilejowanego. W tym drugim

Page 11: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 11

rozkazy, które mogą zachwiać stabilnością systemu są traktowane tak, jak rozkazy nieistniejące, czyli są niedostępne. W jaki więc sposób przechodzić do trybu uprzywilejowanego i kiedy z niego wychodzić, oraz kiedy się to tak naprawdę dzieje?

Najpierw uświadomimy sobie, że przejście z uprzy – do nieuprzywilejowanego jest bezpieczne. Jak więc przejść w drugą stronę? Wykorzystujemy mechanizm przerwań programowych – specjalnych rozkazów, które powodują przeniesienie naszego sterowania w odpowiednie miejsce pamięci wraz ze zmianą trybu. Przerwanie programowe a nie skok, bo skok może być wykonany w sposób dowolny, można skoczyć w dowolny adres , a przerwanie programowe powoduje aktywowanie pewnej procedury ,której adresu nie jesteśmy w stanie zmienić, a dlaczego o tym dalej. Czyli wywołujemy prawie to co chcemy, ale to co się wykona nie zależy już od nas, to co się wykona jest elementem napisanym prawdopodobnie przez innego programistę, nie jest składnikiem naszej aplikacji. Przejście wykonywane jest przez procedurę przerwania programowego, a kod jest kodem systemu operacyjnego, nie kodem aplikacji użytkownika. Wchodzimy w tryb uprzywilejowany oddając sterowanie do systemu operacyjnego. W linuxie mamy shutdown, zwykle administrator wywołuje go. Ale to nie wystarczy. W kodzie programu shutdown znajdziemy wywołanie procedury systemu operacyjnego, która prowadzi do zamknięcia systemu, a nie hasełko halt. Będzie tam przerwanie programowe z zabezpieczeniem rejestrów. To jest dobre, bo pracujemy w trybie uprzywilejowanym, ale możemy wykonać tylko to, co było zapisane jako procedura obsługi tego przerwania, system sprawdzi, czy mamy prawa dokonać zamknięcia systemu. Ciekawostką jest tu to, że w przedpotopowych kompach wejście do przerwania programowego było realizowane w dziwaczny sposób, w kompie PDP8 wejście do sys operacyjnego trzeba było podzielić przez 0…

Ostatnia rzecz odnośnie wsparcia toSprzętowa ochrona pamięciMożemy wyrzucić globalne instrukcje oddziaływujące na nasz procesor typu halt itp. do trybu uprzywilejowanego. W dalszym ciągu na liście rozkazów procesora zostanie masa rozkazów o charakterze potencjalnie niebezpiecznym i nie da się ich usunąć bo np. są to operacje swobodnego zapisu i odczytu pamięci operacyjnej. Niebezpieczne to może być dlatego, bo jeśli byśmy swobodnie się bawili pamięcią operacyjną, to moglibyśmy zmienić przestrzeń adresową jakiegoś procesu albo zmienić fragment pamięci systemu operacyjnego, on przecież opracuje w jakiejś przestrzeni adresowej. Modyfikacja pamięci wiec to jedno. Po drugie instrukcje swobodnego skoku po pamięci operacyjnej są potencjalnie niebezpieczne, np. skoczymy z jednego programu do miejsca, które jest procedurą dokonywania walidacji hasła, w ten sposób odkryjemy hasło administratora przy pomocy pewnych trików w kodzie. Możemy jednak ograniczyć możliwości użytkownika jeśli chodzi o zakres parametrów tych instrukcji, czyli użytkownik może czytać pamięć, zapisywać, skakać, ale rozmiary adresów, rozkazy adresów będą ustalone i nieprzekraczalne. Rejestry bazowe i rejestry graniczne wyznaczają dopuszczalne operandy odpowiednich rozkazów (skoku i …). To trochę na tej zasadzie, że deklarujemy 100elementową tablicę, a odwołujemy się do elementu dwusetnego. Czyli to już jest poza naszą przestrzenią adresową. Ustalanie rejestrów jest tylko dla trybu uprzywilejowanego.

System operacyjny składa się wg klasycznej nomenklatury z (i realizuje zadania):

Zarządca procesów odpowiedzialny jest za: - tworzenie i usuwanie procesów, - wstrzymywanie i wznawianie procesów, - synchronizowanie procesów, czyli zapewnianie odpowiedniej kolejności ich wykonywania, - komunikacja międzyprocesowa (by mogły sobie gadać, ale nie psuły sobie przestrzeni adresowych); - dostarczanie mechanizmów obsługi blokad (powstaje to wtedy gdy proces żąda dostępu do zasobów w różnej kolejności, takie zakleszczenie), typu jedna osoba wzięła garnek,

Page 12: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 12

druga przykrywkę i się szukają, ale nie mogą znaleźć, bo produktów nie ma na półce i się kręcą w kółko ;) wtedy system operacyjny jest jedynym mediatorem, musi on zabić jeden z tych procesów.

Zarządca pamięci operacyjnej- utrzymuje ewidencję wolnych i zajętych fragmentów pamięci operacyjnej;- przydzielanie i zwalnianie obszarów pamięci stosownie do potrzeb

Zarządca pamięci masowych i systemów plików- ewidencja urządzeń pamięci masowej- ewidencja wolnych i zajętych fragmentów poszczególnych urządzeń- odwzorowanie strumienia danych na tablicę bloków dyskowych- usługi nazewnicze i katalogowe- podstawowe operacje na plikach i katalogach

Podsystem wejścia wyjścia- ukrycie specyfiki obsługiwanych urządzeń wejścia wyjścia

Podsystem ochrony- identyfikacja użytkownika- ustanowienie relacji proces – prawa dostępu- ochrona zasobów przed nieautoryzowanym dostępem- zarządzanie rozliczaniem (limitowanie dostępu do zasobu)

Podsystem sieciowy (opcjonalnie)Zadania oczywiste…komunikacja w środowisku sieci.

Interpreter poleceń ./ menager programów (opcjonalnie)Coś co pozwoli nam ruszyć wykonanie całego procesu z miejsca. Kod nie będzie już kodem uprzywilejowanym. Coś musi być bezpośrednio nad systemem operacyjnym.

Proces to wykonujący się program. Programem zaś jest coś wykonywalnego co leży w postaci zestawu plików w pamięci masowej. Uruchamiając ów program tworzymy jeden lub wiele procesów, które wykonują pewien kod. Oczywiście w pamięci jest wiele plików wykonywalnych, ale nie każdy musi mieć reprezentację w postaci procesu, podobnie w drugą stronę, czyli nie ma jednoznaczności tutaj.

Diagram stanu procesuTeoria mówi, że proces może znajdować się w jednym z 4 stanów:

1. Dormant (nieustalony, martwy) – proces znajduje się w tym stanie przed swoim powstaniem i po swoim zakończeniu działania, jak zostawimy ten proces to będzie nam po prostu łatwiej narysować diagram

2. Active running (aktywny, wykonywany) – stan w którym proces wykonuje swój kod. Chodzi o taką sytuację, w której procesor wykonuje kolejne instrukcje jego logiki, ta sytuacja nie zawsze występuje. Jeśli procesor jest w stanie niskim, to jego kod de facto nie posuwa się do przodu.

3. Ready (gotowy) – gdy powinien wykonywać swój kod, ale nie ma wolnego procesora, który mógłby to czynić

4. Suspended / sleeping / awaiting (wstrzymany, uśpiony, czekający) - proces oczekuje na przydział jakiegoś zasobu, bądź realizację zamówionej operacjiwejścia, wyjścia.

Pierwszym wydarzeniem w życiu procesu to powołanie go do życia.

Pytanie do jakiego stanu jest to przejście? Wiadomo, że nie do stanu wstrzymanego, bo w ten stan proces wchodzi po zamówieniu operacji wejścia wyjścia lub po zamówieniu zasobu, a zatem przed tym zamówieniem

Page 13: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 13

trzeba wykonać jakieś instrukcje procesora, które powiedzą nam czego chcemy. Zatem każdy proces zaczyna się od jakiejś części obliczeniowej, czyli dotknie stanu aktywnego. Pytanie czy dotknie go od razu? Z jednej strony po to proces się narodzi, by podjąć jakąś aktywność, ale można też z drugiej strony powiedzieć, że najpierw w momencie narodzenia procesu system rezerwuje pamięć itp. A proces ustawia w kolejce do wykonywania, czyli klasyczna sytuacja gotowości.

Dlatego jako pierwszą rysuje się strzałeczkę narodzin procesu od Dorman do Ready.

Potem przechodzi w stan Active, wcześniej czy później będziemy musieli zacząć go wykonywać. Ten akt nazywa się zaszeregowaniem, albo przydziałem procesora CPU.

Trochę kodu wykona, ale wcześniej czy później będzie chciał zamówić operacje wejścia wyjścia i tym samym zrzeknie się procesora, czyli przejdzie w stan wstrzymania Sleeping.

W końcu zostanie z niego wyprowadzony, nastąpi przerwanie, które spowoduje, że stan się zmieni na stan umożliwiający kolejne zaszeregowanie. Po zakończeniu operacji wejścia wyjścia nie wiadomo czy od razu kod będzie się dalej wykonywał, bo nie wiadomo jakie będą warunki, dlatego zakończenie operacji wejścia wyjścia to przejście do stany Ready. Ładny rysunek jest tu u Frendzla str 5.

Myślimy czy z jakiegoś stanu w ogóle dojdziemy do stanu dormant?Drogą eliminacji dochodzimy do wniosku, że przejście ze stanu Active do Domant to zakończenie procesu.

Jest jeszcze droga z Active do Ready – odebranie procesora i przejście do stanu oczekiwania, czyli wywłaszczenie. Istnieje funkcja yield();, to taka dziwna instrukcja, która powoduje że proces sam się wywłaszcza. Przykład absurdu :For(;;)yield();

Czyli jest możliwe nieprzymusowe wywłaszczenie. Ale ogólnie to mamy wywłaszczenie czasowe i wywłaszczenie priorytetowe, czyli w kolejce pojawił się proces, który ma większy priorytet. Pamiętamy, że wywłaszczenie jest cechą systemów wielozadaniowych. W systemach czysto wieloprogramowych mogą występować wywłaszczenia drugiego rodzaju. Wywłaszczenia czasowe nie są obowiązkowe, by sobie zrobić złudzenie wielozadaniowości, bo w sumie można próbować to jakoś ominąć typu podnosić sztucznie priorytety procesów w kolejce, ale z drugiej strony to też musi być to wywłaszczenie by system w ogóle tą kolejkę mógł przejrzeć więc…

Ile jest procesów w danym systemie naraz?Ile jest tych procesów w stanie dormant jest bez sensu. Procesów aktywnych jest maksymalnie tyle, ile procesorów. Natomiast minimalnie…hmm…Pytanie co robi procesor jak nic nie robi, czy faktycznie może nie być uruchomionego żadnego procesu? Jak zrobimy program, który będzie sprawdzał ile jest procesów aktywnych w systemie to zawsze on wskaże przynajmniej jeden czyli samego siebie, ale nigdy w sumie nie zobaczymy sytuacji w której nie ma żadnego. Ale z drugiej strony może system wywłaszcza procesy aktywne, czyli pytanie czy system, procesor może odróżnić proces aktywny od gotowego…W sumie więc nie jesteśmy w stanie dokładnie określić stanu systemu.

Jest coś takiego jak pętla biegu jałowego, coś o najniższym priorytecie, a musi być bo procesory Intela nie potrafią nie robić nic, a tak to każdy inny proces go wywłaszczy. W

Page 14: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 14

pętli biegu jałowego jest podbijana wartość znacznika, który potem służy do określenia utylizacji naszego procesora, stopień zaangażowania systemu w działania. Czy pętla biegu jałowego jest procesem? Jeśli tak to wtedy procesów byłoby zawsze tyle ile procesorów.

Ile jest procesów w stanie gotowości? Teoretycznie nieskończenie wiele, teoretycznie, bo jakieś limity systemowe zawsze są. Analogicznie taka sama sytuacja jest z procesem wstrzymania.

Co gdy procesów gotowych jest więcej niż zwykle bywało?Wyobraźmy sobie, że mamy pewną liczbę procesów gotowych utrzymujących się w systemie i gdy ta liczba wzrośnie, to stał się on bardziej ociężały, potrzebuje więcej mocy obliczeniowej. Można więc zaproponować jeden z dwóch rodzajów upgrade’u:- upgrade prędkości procesora, typu wyjmujemy stare procesory i wkładamy nowe szybsze procesory – wzmocnienie mocy obliczeniowej - montujemy zamiast 2 procesorów, 4 procesory. – zwiększenie liczby procesorów

Załóżmy że prędkość przetwarzania jest wprost proporcjonalna do szybkości taktowania. Powiedzmy, że mamy jeden procesor wyposażony w 4GHz oraz drugi przypadek: 4 procesy po 1Ghz. Nie ma żadnych powodów, by wybrać drugą opcję, bo system pierwszy jest w stanie za pomocą mechanizmów podziału czasu może udawać drugi, a drugi nigdy nie będzie udawał pierwszego. Jak mamy jeden proces to druga opcja jest 4 razy wolniejsza od pierwszej. Gdy procesów jest więcej niż 4 to te systemy są całkowicie równoważne. Teoretycznie w drugiej opcji możemy się pobawić wywłaszczeniami, ale…Wybiera się i tak drugą opcję, bo nie da się zrobić pierwszej dobrej, więc mamy maksymalnie dobrą pierwszą opcję typu nHz i potem tworzymy takie sytuacje, które mają jakąś liczbę tych nHz.

Gdy mamy więcej niż zwykle procesów wstrzymanych, to sytuacja jest mało jednoznaczna, bo duża liczba procesów wstrzymanych może być w ogóle przez nas niezauważona,. Dobrze się uchronić od myślenia, że procesy wstrzymane są dlatego, bo oczekują na wykonanie jakiś operacji wejścia wyjścia, które się ślamazarzą, bo np. dysk jest za wolny. Gdy powiedzmy jest dużo wstrzymanych procesów w serwerach WWW bo serwery te czekają na klienta który się pojawi, by coś się mogło zacząć dziać.

Jeżeli mamy bardzo dużą liczbę procesów wstrzymanych musimy pomyśleć czy nasz system nie będzie potencjalnie ZA CHWILE cierpiał z powodu za małej ilości pamięci operacyjnej. Jest możliwość, że procesy wstrzymane są wsadzone do pamięci masowej –akcja w systemach wirtualnych, ale wtedy gdy pojawia się aktywność, to trzeba wrócić z tymi procesami i to już powoduje pewne opóźnienie, zatem w tej sytuacji dobrze pomyśleć, czy nie upgrade’ować pamięci operacyjnej. Wzrost mocy obliczeniowej niewiele da.

Przykład pacjenta i kozetki – Frendzel strona 7. Uzupełnienie do tego: powiedzmy, że wszystkie te elementy tj. C,L,S,R są zasilane jednym procesorem. Uznajemy, że pełny cykl C to 3 jednostki czasu, ¼ czasu zabiera przygotowanie operacji wejściowej z pierwszej elektrody. Potem ¾ odzew z tej elektrody.

L: pół jednostki czasu zajmuje mu zamówienie operacji na jednym dysku, 1,5 jednostki to oczekiwanie na odpowiedź i potem znów pół to zamówienie operacji na drugim dysku i znów 1,5pkt.

S to czysta obliczeniówka, przetworzenie jednych danych na drugie, powiedzmy, że zajmie to dwie jednostki.

Page 15: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 15

Raportujący program ma dwa zegary, czyli zamówienie operacji wyjściowej na jednym zegarze i potem na drugim. Zamówienie trwa ¼ jednostki czasu, a realizacja 1i3/4 jednostki czasu.

Rytm pracy całego systemu to może być tym systemu jednoprogramowego, gdzie poszczególne procesy są wykonywane sekwencyjnie jedne za drugim, albo wielozadaniowego, gdzie te procesy się schodzą i następują próby pogodzenia tych systemów.

Jednoprogramowo jest łatwe do analizy. Zbieramy dane, zapisujemy na dysku, przeliczamy, wyświetlamy, zbieramy, zapisujemy, przeliczamy, raportujemy. Interesuje nas jak często próbkowany jest pacjent i jakie jest opóźnienie pomiędzy jego stanem, a wyświetleniem na zegarach - to podstawowe miary wydajności tego systemu. Próbkowanie można zmierzyć po początkach dowolnego z tych procesów np. C. Opóźnienia to zaś pomiędzy początkiem C a końcem R. C+L+S+R = 3+4+2+3=12TU(Jednostek czasu)

Utylizacja CPU(wysokie stany) C+L+S+R = 0,75 + 1 + 2+0,5=4,25Czyli utylizacja to 4,25/12 = 35%, czyli 65% jest w stanie wstrzymanym. Czy umiemy poprawić wydajność bez zwiększania szybkości urządzeń wejścia wyjścia czyli bez skracania czasu faz niskich? Możemy załatwić sobie wieloprogramowość, ale ona musi być ładnie zsynchronizowana, sama duża ilość procesorów nie wystarczy, bo zwykle są nierówno obciążone owe procesory.

U nas synchronizacja wygląda tak:Jak zbierzemy dane, to na nich współbieżnie mogą pracować procesy przeliczające je i zapisujące na dysku. Dopiero po całkowitym przepisaniu, możemy uruchomić program pokazujący je na zegarkach. Następny program kolekcjonujący dane musi być uruchomiony po programie L i S, bo inaczej nastąpiłoby nadpisanie danych. Kontynuujemy i będzie strzałka R->S (Frendzel), strzałki pionowe to ochrona dwóch buforów. Czyli Nawet jeśli kupimy maszynę czteroprocesorową, to nie puścimy na niej czterech programów, bo one muszą być ze sobą odpowiednio zsynchronizowane, choć jakiś tam zysk by był.

Puszczenie procesu L najpierw ma sens, bo będzie zysk, L ma dziury, i w te dziury wsadzimy części S –wieloprogramowość pionowe linie Frendzel strona 8, gdybyśmy podeszli odwrotnie to póki S się nie zrzeknie procesora to L nie ruszy.

Ogólnie jak mamy puścić dwa procesy to lepiej najpierw puścić ten, który ma mniejsze zapotrzebowanie na moc obliczeniową. Priorytetujemy te procesy, które mają mniejsze zapotrzebowanie! Czyli u nas puszczamy najpierw fazę obliczeniową L, a S jest w stanie gotowości, potem L się zagłębia w fazę oczekiwania na wejścia-wyjścia, a S sobie działa. Gdy L skończy to S wywłaszczamy i przekazujemy procesor procesowi L, inaczej byśmy mieli pół jednostki czasu opóźnienia. Kosztem przesunięć jest to, że S zakończy się później, czyli R później wystartuje, ale nadal to się opłaca, prędkość przetwarzania jest większa w tym układzie. Czyli proces L zwycięża nad S dwa razy – na początku i w momencie wywłaszczenia priorytetowego. Proces R nie jest zależny od L, więc puszczamy go z końcem S. Zęby procesu C2 nie zachodzą na zęby procesu R2, tak są dobrane te wartości, by nie było rywalizacji o procesor. Samo wyszło, że można zrezygnować z synchronizacji R1 i S2, bo jest różnica jednostki czasu między nimi.

Wyszedł diagram czasowy wykonywania całego zbioru procesów. Po przeliczeniu wychodzimy, ze teraz bez żadnych upgradeów sprzętowych mamy opóźnienie już nie co 12TU tylko co 7TU. Teraz utylizacja jest rzędu ponad 50%. Możemy dalej ulepszać bez upgrade’ów. Zatykamy się, bo używamy tego samego bufora do odczytu danych i

Page 16: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 16

pobrania do następnego programu, wiec lepiej by w nieparzystych obiegach zapisywał do jednego bufora pamięci, a parzystych w innym buforze, czyli znów byłoby szybciej.

Czy jak będziemy odpowiednio szeregować zadania, to czy poprawimy naszą sytuację? Gdy systemy pracują w warunkach małego obciążenia, to wszystkie powinny się w sumie zachowywać tak samo. Różnice pojawiają się w momencie, gdy mamy do czynienia ze zwiększonym zapotrzebowaniem na moc obliczeniowa albo gdy mamy dużo procesów do wykonania. Wtedy właśnie Są różnice miedzy systemami i wtedy jeden jest do jednych zastosowań lepszy, a do innych gorszy. Serwer WWW możemy uruchomić na mocno desktopowym systemie typu Windows 9x, gdy będziemy go używali za pomocą przeglądarki zainstalowanej na tym samym komputerze itp. Gdy uruchomimy ten system na laptopie to Gucio. System, sprzęt musi być dostosowany do warunków użytkowania,. Gdy na lapku zainstalujemy inny system np. Windows w wersji serwer to będzie się zachowywał dużo lepiej.

Kryteria algorytmów szeregowania zadań

1.Utylizacja

Utylizacja - Suma obliczeń w jednostce czasu. Utylizacja to nie jest coś, co jest złe. To coś typu gorączka w organizmie, to nie

jest przecież złośliwa działalność mózgu, tylko reakcja obronna. Tak samo podnoszenie się utylizacji w systemie zachodzi po to, by zadania zlecone naszemu systemowi były wykonywane jak najszybciej. Po to maksymalizujemy utylizację, by wszystko odbyło się jak najszybciej. To jak ten systemik co ostatnio rozmawialiśmy, początkowo miał utylizację 35%, a gdy zrobiliśmy tak by więcej procesów naraz się wykonywało, to czas był lepszy, ale utylizacja wzrosła do ponad 50%. Czasami utylizacja może być powodowana przez zjawiska negatywne typu wirująca blokada - źle napisany program wpada w nieskończoną pętlę i to też będzie powodowało 100% utylizacji. Jednak utylizacja jest miarą korzystną, ten algorytm będzie dla nas lepszy, który będzie miał wyższą utylizację, który będzie dociążał nasz komputer, a nie odwrotnie.

2. Przepustowość

Przepustowość - liczba procesów kończonych w jednostce czasu (koniec zamierzony, elegancki).To dobra miara gdy do systemu dociera wiele procesów i szybko giną. Ta miara się przyda, gdy na kompie pracuje mocno obciążony serwer pocztowy. Tym lepszy algorytm im przepustowość wyższa.

3. Czas cyklu przetwarzania

Mamy do czynienia z tym elementem, gdy system wykonuje zadania w sposób ciągły jednolitego charakteru - przykład to ten nasz system diagnostyki medycznej, tam właśnie nas interesuje średni czas cyklu przetwarzania. Czas ten powinien być jak najkrótszy.Czas cyklu przetwarzania to średni czas życia procesu ( przydaje się gdy procesy startują i się kończą).

4. Średni czas oczekiwania

Średni czas oczekiwania to stosunek czasu spędzonego przez proces w stanie gotowości do całego czasu przetwarzania. Chcemy by ten czas był jak najmniejszy. Zerowy by był wtedy, gdybyśmy mieli tyle procesorów ile procesów, ale oczywiście tak się nie da.

Stan gotowości procesu jest w sumie niekonstruktywny, bo tu mamy opóźnienie wywołane niedoborem pewnego zasobu, to co innego niż stan opóźnienia. Tam ten brak

Page 17: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 17

aktywności zwykle jest spowodowany tym, że nikt nie chce korzystać z naszego serwera. Natomiast tu stan ten jest dlatego, bo nie ma wolnego procesora.

Metody stosowane w algorytmach szeregowania

Te metody to wzory ogólne, bo w życiu stosowane są mieszanki tych algorytmów.

Algorytm FCFS (First Come First Served, FIFO)W prostych systemach desktopowych, systemach stacji roboczych wystarczało. Kolejka procesów gotowych jest kolejką FIFO, proces który chce dostać się do procesora jest umieszczany na końcu tej kolejki. Procesor jest przydzielany procesowi z czoła kolejki. Jest to taka w sumie sprawiedliwa kolejka do sklepu ;)

Zalety- ekstremalnie prosty, nie ma problemu z implementacją, a jest to ważne, bo fajnie by rzecz, która ma decydować o tym, jak będzie się zachowywał system w warunkach dużego obciążenia, nie powodowała sama owego obciążenia.- w systemach jest coś takiego jak głodzenie (starvation), czyli sytuacja w której pewien proces nie dostaje jakiegoś zasobu (niekoniecznie procesora) dlatego, że ciągle w dostępie do tego zasobu uprzedza go proces, który ma do tego większe prawa. Czyli ważniejsze procesy wpychają się przed nas, wtedy ogólnie kolejka się nie posuwa do przodu tylko wciąż są wykonywane tylko procesy z wysokim priorytetem, wtedy mamy głodzenie procesów niskopriorytetowych. Takie głodzenie się faktycznie zdarza. Tutaj nie ma czegoś takiego, wszystkie są wykonywane kolejno.

Wada- jeśli proces przed nami się zawiesi to koniec – wada kolejki FIFO, czyli grozi nam zawłaszczenie obliczeniowe.- efekt konwoju: wyobraźmy sobie, że podjeżdżamy wózkiem do kasy w supermarkecie, w którym jest jeden produkt, a przed nami są wielkie wypełnione wózki. Konwój skutkuje wydłużeniem się średniego czasu oczekiwania. Załóżmy, że do kolejki trafiły 3 procesy w tej kolejności: 24TU,3TU,3TU czyli pierwszy nie czeka w ogóle, drugi czeka 24 jednostki czasu a trzeci czeka 27 jednostek, czyli średni czas oczekiwania to 17, a jeśli puścimy odwrotnie to średni czas oczekiwania będzie 3. Niby to manipulacja danymi, bo i tak wszystko musi się odbyć, ale czujemy, że jak mierzymy dobroć całego układu, to jednak ma znaczenie, bo jak puścimy tego jednego człowieka z puszką w wózku, to szczęście tej osoby będzie znacznie większe niż straty tj. czas oczekiwania tych dużych wózków. Przydałoby się też tak, że osoby z małymi wózkami są przepuszczane, by się ich nie mnożyło przez to, że muszą czekać aż te duże będą obsłużone.

Wyobraźmy sobie system, który robi dwie rzeczy: wykonuje pewne zadanie obliczeniowe i realizuje rzeczy serwera WWW – wypycha małe kawałki do sieci. Pojawienie się zapotrzebowania na mały dokument byłoby ustawienie go na końcu po tych dużych obliczeniach. To takie coś jak lagi – opóźnienia. Gdyby przepychać szybkie, krótkie zadania, to on byłby szybko reaktywnym serwerem WWW, a jednocześnie liczył w miarę ok., byłoby opóźnienie w tym liczeniu, ale ta strata byłaby malutka. Oczywiście tutaj też ma znaczenie priorytet tych obliczeń.

W większości zastosowań serwerowych bardziej interesuje nas reaktywność. Natomiast na stacjach roboczych może interesują nas bardziej te wagoniki. Czyli FCFS to raczej na stacjach roboczych. O tych krótkich procesach często mówimy , że są nastawione na wejście, wyjście, a te duże - że są nastawione na obliczenia.

Page 18: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 18

Zróbmy wiec teraz zamiast kolejki sprawiedliwej, kolejkę super niesprawiedliwą:

Algorytm SJF (Short Job First)

Czyli najpierw idzie to zadanie, które ma najkrótszą fazę obliczeń.

ZaletaJest to algorytm optymalny ze względu na średni czas oczekiwania.

W supermarkecie kasjer by przeglądał całą kolejkę towarów – sprawdzałby czy na każdym produkcie jest metka itp., obliczałby czas wykonania transakcji z wózkiem, potem przechodzi do kolejnego wózka itp. Po czym oznajmia wynik. Czas zużyty przez kasjera na wytypowanie najlepszego wózka jest znacznie dłuższy niż sama obsługa. Tak samo gdybyśmy chcieli stwierdzić, który proces wykona się najszybciej, bierzemy pierwszy proces, pierwszą instrukcję i sprawdzamy ile czasu by się ta instrukcja wykonywała, potem drugą instrukcję itd., potem drugi proces itd. I dopiero jak je wszystkie sprawdzimy to możemy wiedzieć, od którego zacząć. Jest to algorytm niewdrażalny, to tylko model który może nam służyć do porównań.

Przybliżmy wiec może ten algorytm, by był wdrażalny. Jak proces był kiedyś grzeczny, to jest szansa, że będzie grzeczny dalej, czyli jak początkowo sobie jakoś pykał, to pewnie za jakiś czas znów pyknie tak samo, a jak był niegrzeczny to że znów będzie niegrzeczny. Są też rozwiązania pośrednie, z nimi jest zawsze najgorzej.

Algorytm średniej ważonej

Przybliżenie SJF, prosty i sprytny. Wzór na spodziewany następny czas obliczeń:

(*) Tn+1=a *tn +(1-a)Tn

Tn+1 – przewidywany czas wykonania najbliższej fazy obliczeń procesu.Tn – przewidywany poprzednie czas trwania j fazy obliczeń.tn – rzeczywisty czas trwania poprzedniej fazy obliczeń procesu.a - stała z przedziału [0,1] (stałą a można zmieniać aby zoptymalizować wykonanie procesu).

Przypadki a=0 (w tym przypadku dostaniemy FIFO) czy a=1(Proces będzie zachowywał się identycznie jak w procesie poprzednim) są trywialne i nie ma co ich rozważać.

By zobaczyć, jak ten wzór działa, rozpisujemy go rekurencyjnie i otrzymujemy:

Tn+1=atn+(1-a)tn-1+(1-a)2atn-2+(1-a)3atn-3+…+(1-a)katn-k+…

Wszystkie współczynniki są coraz mniejsze, bo dla a – ułamek zwykły to mamy najpierw jeden ułamek, potem ułamek * ułamek itp., czyli coraz mniejsze wagi, stąd Tn+1 zależy najbardziej od długości poprzedniej fazy obliczeń, mniej od poprzedniej, itd.Najważniejszy jest czas ostatniej fazy procesora.

Czyli patrząc na ogólny wzór (*) dla każdego procesu musimy wykonać 5 działań arytmetycznych (dwa mnożenia, dwa dodawania i jedną zmianę znaku) i wybieramy proces o najmniejszej spodziewanej fazy procesora. Pytanie więc czy to co wyjdzie jest faktycznie dobre?

Page 19: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 19

(1)

(2)

(3)

przewidywana następna faza obliczeń

Proces (3) zachował się inaczej niż przewidywaliśmy, spowodował nam lag - opóźnienie, spowodował efekt konwoju, ale jednocześnie w kolejnym przejściu proces dostanie karę, spadnie niżej w hierarchii procesów. Proces (2) w systemach działających o algorytm średniej ważonej jest mało negatywny, bo trochę popracuje, potem dostanie w czapę, system pracuje jakby nigdy nic i gdy będzie czas to mu odda procesor. Natomiast proces (3) wciąż odbudowuje zaufanie systemu, generuje proces konwoju, traci zaufanie i od nowa. Jednak gdy proces się zawiesi to system mu ładnie szybko obniży priorytet i będzie ok. Statystycznie to przybliżenie jest ok.

Wszystkie algorytmy opierające się na przepuszczaniu zadań nastawionych na wejście wyjście, krótką fazę obliczeniową oczywiście cierpią na problem głodzenia, bo może się pojawiać wiele procesów o krótkich fazach obliczeniowych. Pytanie co gdy nadejdzie proces o jeszcze krótszym czasie wykonywania niż aktualnie wykonywany proces –najefektywniej będzie, jeśli on wywłaszczy ten który teraz chodzi, czyli mamy wywłaszczenia priorytetowe.

Algorytm priorytetowy (planowanie priorytetowe)

Każdy proces jest wyposażony w cechę liczbową zwaną priorytetem, w kolejki procesów gotowych wybierany jest proces o najlepszym priorytecie. (najlepszy może oznaczać najniższy). W przypadku równych priorytetów stosuje się porządek FIFO.

Zaleta- prostota, opiera się przecież na wyszukaniu naj(większego) elementu w tablicy - można wyróżnić jedną grupę procesów nad inną, można ustalić, że jedne procesy są ważniejsze niż inne.

Wada- wadą wszystkich algorytmów priorytetowych jest głodzenie

Rozwiązanie problemu głodzenia – postarzanie procesówCo pewien czas sprawdzamy kolejkę procesów gotowych i te które przebywają w kolejce bardzo długo, to mają sztucznie podnoszony priorytet, to się dzieje raz na jakiś czas, a nie przy każdym obiegu, by nie dojść do kolejki FIFO. Pytanie kiedy mu ten priorytet zabrać, czy tuż po tym jak się go wypchnie z kolejki procesów głodzonych ,to jak się on zrealizuje, to znów po dojściu do stanu gotowości zacznie być głodzony. Lepiej wiec stopniowo mu ujmować ten priorytet, w ten sposób on będzie pływał na granicy głodzenia i normalnej pracy.

Round - Robin (rotacyjny) (wersja prowadzącego - w koło Wojtek ;))

Modyfikacja algorytmu FIFO, polega na dołożeniu wywłaszczenia czasowego do wykonywanego procesu i przepchnięcia go na koniec kolejki, takie FIFO z poprawką, eliminuje to, że jest w czystym FIFO możliwość wywłaszczenia czasowego, ale nadal nie jest usunięta wada polegająca na efektach konwoju, tylko trochę ten problem zmniejszy, ale go nie likwiduje. Im szybciej wywłaszczamy tym mniejsze konwoje, ale jeśli wywłaszczamy bardzo szybko, to w limicie czasu jesteśmy w stanie wykonać bardzo mało

Page 20: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 20

instrukcji procesora, a czas zużyty na wywłaszczenie czasowe i jego obsługę może być podobnego rzędu… Wtedy udział algorytmu szeregującego w całym procesie przetwarzania zadań jest bardzo wyraźny, czyli system byłby wolny bez wglądu na to które zadania by faworyzował. Musi być tak, że liczba instrukcji wykonywana w limicie czasu jest kilka rzędów wyższa niż ilość instrukcji wykonywana podczas wywłaszczenia, czyli fajnie by wywłaszczenia były jak najbardziej przeźroczyste, czyli pod tym kątem przyda nam się jak najdłuższy czas co jaki następuje wywłaszczenie.

Kiedyś to była 1/10 sekundy. Wtedy użytkownicy nie cierpieli za bardzo na efektach konwoju, a obecnie ten czas można zmniejszyć do 10 a nawet do 1 milisekundy. To coś co całkiem nieźle broni nas przed efektami konwoju, a w tym czasie wykona się dużo instrukcji procesor, więcej niż wykonuje się podczas wywłaszczenia. Ale z punktu widzenia serwera WWW, który wykonuje setki transakcji na sekundę to 1ms jest to dużo, wtedy te opóźnienia moglibyśmy jednak odczuwać. Round-Robin zdarza się rzadko w systemach operacyjnych, w czystej postaci występował on tylko w systemie Windows 9x. Tam było tak, że limit czasu dla procesu pierwszoplanowego był większy niż dla procesu pracującego w tle.

Algorytm kolejek wielopoziomowych

Algorytm ten łączy te wszystkie algorytmy w jedno. Procesy dzieli się na klasy abstrakcji o różnym priorytecie. Każda klasa ma odrębną kolejkę procesów gotowych obsługiwaną według odrębnego algorytmu szeregującego. Do wykonania wybiera się proces najwyższej klasy, chyba że kolejka tej klasy jest pusta, wtedy przechodzi się do analizy następnej klasy. Aby zapobiegać głodzeniu, możemy przenosić procesy do kolejek wyższych klas – nazywamy to promocją. Aby zapobiegać zawłaszczeniom obliczeniowym możemy przenosić procesy do kolejek niższych klas – nazywamy to dymisją.

Przykład: kolejka o najwyższym priorytecie

faza CPU<=4

faza CPU >8faza CPU<=16

faza CPU>16

8 , 16 to kwanty czasu. Nowy proces dostaje kredyt zaufania i zawsze trafia do kolejki o najwyższym priorytecie. Scenariusze: proces ten zakończy działanie po 4 CPU, wtedy on wychodzi. Jeśli nasze CPU jest wyższe to następuje wywłaszczenie czasowe, w czystym Round Robin byśmy poszli na sam koniec ale my zastosujemy dymisję, czyli dojdziemy do kolejki o niższym priorytecie, czyli u nas do Round Robin 16. Ale kolejka RR16 ruszy się dopiero jak pierwsza kolejka się opróżni. Z drugiej fazy więc będziemy wychodzili powiedzmy po 16CPU, a jeśli nasz proces jednak jest procesem o dłuższej fazie obliczeniowej to zostanie wywłaszczony I skierowany na koniec kolejki tj do klasy niżej. Tu będzie niefajnie, bo ruszy dopiero jak powyższe dwie kolejki będą puste. Reaktywność systemu będzie wysoka. Nie ma tu elementu promocji, czyli tego co uleczyłoby go z wady: jeśli z dużą częstotliwością nadchodzą nowe zadania z CPU<4 to procesy na samym dole mogą zostać głodzone…

Ten model jest bardzo podobny do tego co naprawdę działa. W Windows NT mamy 32 poziomy kolejek, poniżej 16 mamy Round Robin, a powyżej mamy procesy czasu rzeczywistego, na samym dole ostatni jest FCFS, gdzie chodzi Idle Loop.

round-robin 4

round-robin 16

FCFS

Page 21: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 21

Promocja I dymisja jest ograniczona, proces Np nie może zmienić swój priorytet o 15 tylko Np +-2. Normalny proces pierwszoplanowy ma priorytet 9. A proces drugoplanowy ma priorytet 7, czyli teoretycznie drugoplanowy może mieć większy priorytet niż pierwszoplanowy, gdy pierwszoplanowy cos liczy.

Synchronizacja procesówsynchronizacja – zapewnienie, że pewne operacje (procesy, czynności) wykonywane przez nasze programy będą wykonywane w odpowiedniej kolejności, to co innego niż synchronizacja czasem

Puszczono nam program, który przekładał w kółko elementy w tablicy 10elementowej w sensie najpierw były 0,1,2..9 potem 1,2,3..9,0, następnie 2,3,4..9,0,1 itd. Puszczono go na irecie i były dwa wątki – jeden odpowiada za tą pętlę, a drugi za ustawienie zmiennej tak by się tamta pętla zakończyła dokładnie po jednej sekundzie, chodziło nam o to by zobaczyć, co się zdąży zrobić w ciągu 1 sekundy.

Otrzymaliśmy efekt – w ciągu 1s iret obrócił ponad 25mln tą pętlą rotującą. Jak puścimy go znów to otrzymamy inną ilość, bo to zależy od obciążenia ireta. 26mln to tyle ile iret jest w stanie wyciągnąć. Gdy dołożymy opóźniacze w funkcji rotującej milion pustych pętli to wyszło tylko ponad 500 rotacji. Następnie rotowaliśmy tą tablicą w dwóch niezależnych wątkach sterowania. Wtedy dla opóźnienia milion wyszło dwa razy tyle rotacji co wcześniej, bo iret jest dwuprocesorowy. Gdyby był jednoprocesorowy to pewnie by się wykonało tyle samo. Program dość szybko zgłupiał, dawał dziwne wyniki im większe tempo, czyli im mniejsze opóźnienie. Wynika to dlatego, bo jak często robimy rotacje to one się w dwóch wątkach nakładają na siebie i rotują tablice w trakcie rotacji. Mamy po prostu tu wywłaszczenie czasowe, któremu może podlegać wątek, który wykonał już pół rotacji tablicy. W tym czasie pójdzie ten drugi wątek i zrobi całą rotację, a na koniec pierwszy wątek zrobi ostatnie pół rotacji. Przy zwiększonym czasie trwania rotacji na dwóch wątkach też będzie źle.

Czyli chcielibyśmy coś zrobić z tym wywłaszczeniem – jeśli jeden wątek rotuje tablicą to by drugi nie mógł tego robić - to naprawi nasz program. Wykorzystujemy w tym celu mutex – służy do synchronizacji i właśnie nam pozwoli zrobić to co napisaliśmy we wcześniejszym zdaniu. Zaczynam mutex przed rozpoczęciem rotacji, a kończę po rotacji. Wtedy nawet jak puścimy rotacje bardzo często to i tak będzie program działał poprawnie, choć nastąpiły duże straty prędkości przetwarzania i trzeba o tym pamiętać.

Model sekcji krytycznej

Rozważmy grupę procesów z wyodrębnionymi fragmentami kodu zwanymi sekcjami krytycznymi. Sekcje krytyczne nie mogą być wykonywane przez więcej niż jeden proces grupy (niekoniecznie zawsze przez jeden z nich). Aby proces mógł wejść do swojej sekcji krytycznej musi dostać na to zgodę. Oczekiwanie na tę zgodę nazywamy sekcją wejściową. Po zrealizowaniu sekcji krytycznej proces powinien zasygnalizować, że jest ona wolna. Sygnalizację tą nazywamy sekcją wyjściową. Pozostałą część kodu nazywamy resztą. Aby model sekcji krytycznej funkcjonował poprawnie potrzebne jest spełnienie 3 warunków:

1. Wzajemne wyłączanie - jeżeli jakiś proces znajduje się w sekcji krytycznej, drugi znajdować się w niej nie może (mutual exclusion – stąd nazwa mutex ;))

2. Warunek postępu – wyboru należy dokonać tylko spośród procesów stojących w sekcjach wejściowych i wybór ten nie może być odwlekany (jak były sto lat temu takie instytucje jak PKS zajmujący się wożeniem ludzi w autobusach, to autobusy te były często przeładowane, więc kierowca zachowywał się w ten sposób, że ładował iluś ludzi, stawał w drzwiach, innych nie wpuszczał, ale szukał swoich znajomych, których by jeszcze wpuścił i czekał na tych znajomych – to jest

Page 22: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 22

przykład Niezachowania warunku postępu, nie wiadomo było czy w ogóle znajomi będą chcieli się zabrać)

3. Warunek ograniczonego czekania – dla każdego procesu sekcji wejściowej istnieje ograniczona liczba wejść do sekcji krytycznej innych procesów.

Problem głodzenia – moglibyśmy nigdy się nie doczekać naszej sekcji krytycznej…

Czy synchronizację da się sprowadzić tylko i wyłącznie do spraw programistycznych, czy możemy się pozbawić wsparcia systemu operacyjnego? To pytanie jaki mamy system operacyjny, do czego on jest przeznaczony, jeśli mamy system jednoprogramowy to da się to zrobić bez pośrednictwa owego systemu, ale nie jest to wcale takie proste.

Przykład:Mamy 2 procesy P1 i P2 i chcemy by one synchronizowały swoje sekcje krytyczne czyli by tylko jeden wchodził do środka, a drugi musi poczekać jeśli ma na tą sekcję ochotę ;)

Int który = 0;For(;;){

While(który!=i); // i to numer procesu/*sekcja krytyczna*/Który = 1-i;/* reszta*/

}

Na pewno widać, że do sekcji wejdzie tylko jeden z naszych dwóch procesów, a po przejściu indeks się zmieni i wejdzie ten drugi. Jednak to rozwiązanie ma niedogodności –brak spełniania warunków postępu, jest tylko wzajemne wyłączanie. Jeśli swoją sekcję wykonał P1 to algorytm zakłada, że do sekcji wejdzie proces P2, a co jeśli p2 nie chce tam wchodzić, a p1 zawróci i chce? Przecież p1 może wykonywać swoje sekcje krytyczne częściej. W tym kodzie p1 będzie musiał czekać, aż p2 się zlituje i wykona choć raz swoją sekcję krytyczną. Dlatego nie nadaje się to do synchronizacji ogólnej.

Musimy więc doprowadzić do sytuacji w której mamy do czynienia z sytuacją zgłoszenia zapotrzebowania na sekcję krytyczną. Mamy więc tablicę :

Int flaga[2]{0,0};// Czyli proces ustawiając flagę zgłosi nam zapotrzebowanie na sekcję krytyczną. For(;;){Flaga[i]=1; //włączamy zapotrzebowanie na sekcję krytyczną i czekamy aż takiego zapotrzebowania nie zgłosi drugi procesWhile(flaga[1-i]==1)/*sekcja krytyczna*/Flaga[i]=0; // po zakończeniu gasimy naszą flagę}

Jednak wadą tego kodu jest deadlock – zakleszczenie które powoduje ten algorytm, bo jak mamy pecha to dwa procesy naraz wykonają operację ustawienia swoich flag i zonk. Czyli to jest po prostu złe, nawet nie myślimy jaki warunek jest blee..

Dlatego łączymy te dwa algorytmy ze sobą i otrzymamy całkiem ok. rzecz o nazwie Algorytm Dekkera.

Int który = 0;Int flaga [2] = {0,0};For(;;)

Page 23: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 23

{Flaga[i] = 1;Ktory = 1-i; (*)While (flaga [1-i] ==1 && ktory!=i) // lub while(!(flaga[1-i]==0 || który==i))/* sekcja krytyczna*/Flaga[i]=0;

}

Czyli pytam kiedy przebijamy pętlę while, pętla alternatywna po // mówi nam w pierwszym warunku, że drugi proces nie chciał wejść lub chciał, ale to my byliśmy wyznaczeni. Zauważmy, że nawet gdy obie flagi będą na 1 to i tak nie będzie zjawiska głodzenia. Ratuje nas linijka (*). Powyższy algorytm działa tylko dla 2 procesów, ale dla większej ilości byłby po Prostu bardziej skomplikowany – algorytm Lampota.Jednak pętla while ma charakter obliczeniowy i to nas niepokoi, więc myślimy nad dalszymi modyfikacjami…

Wsparcie ze strony procesora dla synchronizacjiDo tego celu procesor jest wyposażony w odpowiednie rozkazy:

- TAS (test and set)Ustawia wartość pewnej komórki pamięci na 1, a zwraca to co było tam wcześniej. Nie da się wywłaszczyć. Czyli mamy przejście 0 -> 1 albo 1 -> 1. While(TAS(zamek)==1) // czekamy/* sekcja krytyczna */ // interesuje nas czy została wykonana zmianaZamek = 0;

- XCHG(x-change)Niepodzielna zamiana wartości dwóch komórek pamięci – 1 i tego co było, czyli tym razem mamy scenariusze 1 -> 1 lub 0 -> 1.

TAS w tym modelu nie spełnia warunku ograniczonego czekania, nie wiemy, który z procesów się przebije, można to zwalczyć skomplikowanym kodem. Druga wada zarówno TAS jak i XCHG to while(…) jest operacją obliczeniową, czyli znów czekamy na nią aktywnie…TAS i XCHG znajdują się w wewnętrznych kawałkach systemu operacyjnego.

SemaforZmienna całkowita, na której można wykonać dwie niepodzielne operacje P i V.Void P (int * sem){

While(* sem <0) // oczekiwanie na jego nieujemną wartość i wtedy jego obniżenie(* sem ) --;

}

Void V (int * sem){

(*sem)++;}

Powyższe semafory nazywamy semaforami binarnymi, bo ich sensowne wartości to 0 i 1.Jak jeden z procesów stwierdzi, że sem >0, to od razu go obniży, nie będzie sytuacji, by dwa procesy stwierdziły, iż sem > 1 (?), to rozumiemy pod pojęciem niepodzielności.

Page 24: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 24

P(sem)/* sekcja krytyczna */V(sem);

Semafory powyższe niestety cierpią na te same wady co TAS i XCHG. System operacyjny wspomaga synchronizację w ten sposób, że jest wyposażony w semafory uogólnione.

Void P( int *sem){

(*sem) --;If (* sem < 0){

Dołącz_mnie_do_listy_semafora(sem);Uspij_mnie;

}}

Void V(int * sem){

(sem ++);If (* sem <= 0 ){

PROCES *p = pobierz_z_kolejki_semafora (sem);Obudź(p);

}}

Jeśli dołączenie będzie na zasadzie FIFO, to ograniczone czekanie będzie.

Synchronizacja wybawia nas z zakleszczenia.

Zarządzanie pamięcią operacyjną

Synchronizujemy głównie pamięć operacyjną przy udziale zasobów systemu po to, by procesy mogły w niej poprawnie działać. Na razie nie będziemy się skupiać na żadnym konkretnym modelu jej organizacji, tylko przyjmiemy, że pamięć ta to poindeksowana tablica bajtów.

Problem wiązania adresów w kodzie i danych

W procesie kompilacji na wejściu mamy kod źródłowy napisany w języku wysokiego poziomu, a na wyjściu mamy mieć ciąg bajtów, który jest obrazem części wykonywalnej tego programu. Obraz tej części wykonywalnej z pliku wykonywalnego jest wprowadzany do pamięci i ma być w tej pamięci wykonywany. Zrobimy sobie eksperyment myślowy na tablicy: napiszemy prosty program i będziemy go na tablicy kompilować. Main(){

Int x=3; Int y=2;Int z=x+y;Out(z);

}Bez printfa by program był możliwie wiernie odzwierciedlony. Kod w język maszynowym: segment danych będzie składał się z 3 zmiennych całkowitych x,y,z. Powiedzmy, że nie

Page 25: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 25

ma tu alokacji na stosie. Część wykonawcza: inicjalizacja x,y, oraz obliczona zmienna z -pobranie do rejestru x, zwiększenie w rejestrze o y itd.

.dataInt xInt yInt z // zakładamy, że każdy rozkaz jest zawarty w jednej zmiennej całkowitej

X jest zainicjalizowana 3, y jest dwójką, a z nie jest na razie zainicjalizowana czyli ma wartość zero.

.code1 Laduj_rejestr x2 zwieksz_rejestr y3 Zapisz_rejestr z4 Wywolaj_funkcje out // powiedzmy, że parametry z braku stosu są przypisywane przez //rejestr 4 Wywolaj_funkcje exit

Czyli mamy program zapisany symbolicznie w języku niskiego poziomu., Kompilator by to zamienił na kod binarny – określił wartości poszczególnych rozkazów, operandów –powiedzmy, że to są u nas te cyferki po lewo. Powiedzmy, że adresowanie będzie od 10, czyli laduj-rejestr jest 10, x jest 11 itp, ale jak wszystko dalej policzę to int x ma 21 czyli już potem x tez będzie miał 21…. Wszystko sobie ponumerowaliśmy i kompilator się bawi…Tylko jak umieszczę ten program w pamięci o adresie 10 to będzie dobrze działało, bo wszędzie indziej będą inne odwołania, odwoływanie się do miejsc poza jego zakresem itp.. By program był przemieszczalny, to można pomyśleć o zrezygnowaniu z adresacji bezwzględnej. Ale wtedy będzie wolniej i zwykle nie jest używana adresacja względna. Kompilatory zwykle tworzą kod nieprzemieszczalny.

W Dosie program był nieprzemieszczalny, ale tylko w obrębie jednego segmentu pamięci i ten segment mógł być przez system załadowany gdzie chciał, czyli mieliśmy adresację względną. Czyli ograniczaliśmy się do jednego segmentu na kod i jednego na dane. To było w plikach .com z Dosu nierelokowalny(nierelokowalny?), wiąże adresy w trakcie kompilacji, wszystkie adresy zapisane w pliku. Ograniczenie to zostało zniesione w plikach .exe te pliki zostają zapisane na dysku z daną jaką jest tablica relokacji. Jest to mapa miejsc w kodzie programu, które muszą być po załadowaniu zmodyfikowane, aby program był dostosowany do innego miejsca w pamięci niż wyprodukował go kompilator. Wiec nie ma już problemu z tą pamięcią. Exe – wiązanie w trakcie ładowania.

Portale executable - Technika ta umożliwiała przesuwanie kodu i danych do pamięci operacyjnej i obszaru wymiany, nie mają swojego rozszerzenia, mają niby exe, ale to tylko opakowanie, są dostępne tylko w Windowsie. Umożliwia zapamiętanie i wykorzystanie tablicy relokacji w każdym momencie jego działania, dlatego system sobie chodzi z tym kodem po pamięci operacyjnej, jeśli ma na to chęć. To było potrzebne nie tylko do zorganizowania obszaru wymiany, ale ogólnie do optymalizacji pamięci operacyjnej. Adresy są wiązane w trakcie uruchamiania - wykonania, w trakcie żądania tego przez system.

Page 26: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 26

Kolejny archaiczny problem to

Modele optymalizacji wykorzystania pamięci przez procesy

Ładowanie dynamiczne – 1 modelProces składa się z zestawu podprogramów i głównej części sterującej. Każdy podprogram jest wprowadzany do pamięci jedynie wtedy, gdy nastąpiło do niego odwołanie.

Sens tego rozwiązania jest taki, że wszystko polega na uświadomienie sobie takiego oto faktu – jak mamy do czynienia z dużym i skomplikowanym programem o charakterze interaktywnym (dialog z użytkownikiem), to przecież korzystamy z małego kawałka jego kodu, funkcjonalności. Zobacz jak mało wykorzystujemy instrukcji stworzonych do Worda w trakcie normalnego użytkowania. Można więc przyjąć taki punkt widzenia – osoba, która używa Worda w sposób prymitywny zajmuje mało pamięci operacyjnej, a ta która używa go w sposób wyrafinowany zużywa znacznie więcej tej pamięci. Fajnie jednak byłoby nie płacić ceny za to, że ten program jest wyrafinowany, gdy chcemy napisać proste podanie. No i jest po to ładowanie dynamiczne – ładuje się główny trzon wykonawczy i to co robimy, a reszta ładuje się na żądanie. To musi być oczywiście zintegrowane z odpowiednią konstrukcja programu. Rozwiązanie to było kiedyś dość powszechnie stosowanie. By rozwianie mogło zadziałać musi być przygotowany odpowiednio mechanizm wiązania adresów, przeliczania ich. Obecnie ta technika istnieje już tylko w wersji teoretycznej, bo sposób rozwiązania się zmienił.

Łączenie dynamicznePolega na tym, że część wspólną dla wielu procesów umieszcza się w osobnym pliku wykonywalnym. Plik ten ładowany jest do pamięci tylko raz w momencie pierwszego do niego odwołania. Inne programy, które korzystają z tego uwspólnionego kodu jedynie wiążą do niego adresy.

Problem bibliotek dzielonych. Często część współdzielona jest wykorzystywana przez bardzo wiele programów.

Dynamiczne łączenie się opłaca, bo powiedzmy, że standardowa biblioteka c ma 4 mega, to w tym momencie każdy program skompilowany statycznie z tą biblioteka zajmowałby w pamięci co najmniej 4 mega, a dzięki temu, że jest ona wspólna to przecież nasze programy zajmują bardzo mało miejsca.

Wady dynamicznie łączonych bibliotek: problem którego przyczyna jest niezachowywanie przez dystrybutorów kompatybilnością bibliotek dzielonych. Mianowicie często jest tak, że zainstalowanie jakiegoś programu powoduje, że jakiś inny program przestaje dobrze działać mimo, że te programy w żaden sposób nie są ze sobą związane. Prawdopodobnie instalacja tego programu nadpisała bibliotekę dzieloną wykorzystywaną przez nasz stary program. Mechanizm wersjonowania – powiedzmy, że jest jakaś biblioteka dynamicznie łączona w wersji 2 i jak ją nadpiszemy to powinno to dalej teoretycznie działać, ale producenci usiłują poprawić różne kwestie i likwidują niektóre rzeczy, które były potrzebne starym programom… Czyli mamy brak bezwzględnej kompatybilności wstecznej. Poza tym zawsze jakiś Trojan może nam bibliotekę popsuć… Obecnie jest pod tym kątem troszkę lepiej. Dynamicznie łączona biblioteka w windowsie to .dll. Jest lepiej bo jest uprywatnianie dynamicznie łączonych bibliotek, ale to odpowiada ładowaniu dynamicznemu… A nie ma to już nic wspólnego z łączeniem dynamicznym…Tylko są używane mechanizmy łączenia dynamicznego, ale nie ma już uwspólnionego kodu. Niektórzy robią tak, że część jest w programfiles a część w commonfiles, by jak mamy do czynienia z dwoma produktami tego samego twórcy to by one mogły dzielić biblioteki. Czyli dalej mamy ładowanie dynamiczne, bo łączenie dynamiczne jest tylko w sferze systemowej.

Page 27: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 27

NakładkiProgram składa się z głównej części sterującej oraz zbioru części wymienialnych czyli tzw. Nakładek. Program zajmuje w pamięci tyle, ile część główna plus największa z nakładek. Oznacza to, że nakładki wymieniają się sobą w pamięci operacyjnej. Kompletny archaizm, nikt tego nie stosuje, tym bardziej, że wsparcie systemu jest praktycznie żadne. Zawsze ładują się od tego samego miejsca nazywanym buforem nakładek, więc system tylko wspomaga samo to ładowanie do pamięci.

WymianaTechnika, która umarła wraz z systemem Windows w wersji 3. Polega na tym, że kod nieaktywnego programu jest zrzucany do pamięci masowej, a uwolniona pamięć jest przeznaczona na inne cele.

Koniec tych modeli.

Alokowanie pamięciPamięć niech będzie tablicą bajtową. Przydział pamięci operacyjnej jest trudny, skoro jest poszatkowana.

Strategie:

First FitBest FitWorst Fit

Rozważmy sprzedaż żółtego sera. First Fit – jak ktoś nas prosi o ileś żółtego sera to sięgamy po pierwszy lepszy kawałek żółtego sera i z niego odkrawamy żądaną ilość. Best fit – wybieramy taki kawałek sera, który jest możliwie mały, ale spełnia żądania klienta. Worst fit – bierzemy największy kawałek jaki mamy i odkrawamy klientowi kawałek. Z ostatniej strategii nie wykorzystają skrawki nie do wykorzystania, a w best fit jednak jest problem ze skrawkami. Sprzedaż sera w plasterkach (stronicowanie) załatwia nasze problemy ;) Tyle że człowiek ma pożytek z sera w plasterkach, a programy nie mają za bardzo pożytku i muszą kleić te plasterki…

Zawsze jak wykrawamy pamięć to mamy do czynienia ze zjawiskiem zewnętrznej fragmentacja pamięci - powstawanie obszarów, które są nie do wykorzystania.

Programy chcą jeden kawałek pamięci, bo alokacja pamięci jest zwykle tak zrobiona ze pamięć dostajemy w postaci sekwencyjnej tablicy, czyli dla programów nie da nam nic ze damy im dwa kawałki sera / pamięci. Pamięć musi być w spójnym bloku.

Na wykładzie przykład jak to był Dos i Norton commander – nie dawało się uruchomić NC z poziomu logowania, a dokładniej dawało się, ale już kompilator nie poszedł, bo jak dawniej było Dos, potem logowanie, potem logowanie znikało po autoryzacji i NC, a dalej CC, natomiast w tej ciekawej wersji był Dos, potem Login potem NC dopiero wtedy kończył się Login i nagle nie było odpowiednio dużej przestrzeni pamięci spójnej by poszło CC.

Wewnętrzna fragmentacja pamięci operacyjnejKolejna rzecz na którą cierpiały dawne systemy. Mam w pamięci operacyjnej milion bajtów. Zrealizujemy żądanie jednego bloku o rozmiarze miliona bajtów, ale nie pójdzie nam otrzymanie miliona bloków o 1 bajcie, bo zawsze jak dostajemy pamięć, to jest jeszcze wydzielanie informacji o tym bajcie i mamy tą wewnętrzną fragmentację. Jedynym sensownym rozwiązaniem jest poddanie się jej… Czyli pozwalamy na przydzielanie pamięci, ale tylko w odpowiednio dużych blokach. Było w Dosie tak, że pamięć była przydzielana w paragrafach (16 bajtów, wycieki pamięci rzędu 30%), a gdyby użytkownik sam sobie przydzielał po 1 bajcie to mógłby być wyciek większy niż to

Page 28: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 28

o co prosimy. Czyli nie ma rozwiązania problemu wewnętrznej fragmentacji, jest tylko zakrycie tego problemu. Podobnie będzie w stronicowaniu.

TU MNIE NIE BYŁO

Stronnicowanie pozwala na detekcje sytuacji gdy zostaje już mało pamięci operacyjnej w systemie. Wtedy przymulają, zamiast awaryjnie kończyć.

Stronicowanie na żądanie

Każda strona na poziomie logicznym jest wyposażona w bitowy znacznik obecności w pamięci operacyjnej. Odwołanie do strony zaznaczonej jako nieobecna w pamięci operacyjnej powoduje tzw. Przerwanie błędu strony. Przerwanie to jest obsługiwane przez część systemu operacyjnego zwaną zarządcą strony. Zarządca stron sprowadza żądaną stronę do pamięci operacyjnej i wznawia przerwany proces restartując instrukcję, która spowodowała przerwanie. Jeżeli strona nie może zostać wprowadzona do pamięci z powodu braku wolnej przestrzeni w pamięci operacyjnej, któraś ze stron powinna być z niej wyrzucona do innego obszaru przechowywania (na dysk, do sieci itp.).

Przykład (z jednej strony minimalistyczny a z drugiej ekstremalny)Załóżmy, że nasza pamięć operacyjna jest złożona z 4 stron (0,1,2,3) od pewnego procesu trafia do systemu żądanie alokacji trzech stron pamięci.

32 A21 A10 A0

Proces ATTSS.F. S.L (translacja strony fizyczne na strony logiczne)2 21 10 0

Do tego niech będzie plik wymiany o miejscach 4,5,6,7.

Proces BTTSS.F S.L.5 24 13 0

Czyli byśmy mieli teraz

3 B02 A21 A10 A0

765 B24 B1

Page 29: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 29

Czyli mamy 4 strony a potrzeba jest 6 stron. Póki proces B pracuje na swojej stroni zerowej to wszystko odbywa się ok., ale gdy dotknie strony 1 to mechanizm stronicowania na żądanie zatrzyma ten program i rozpocznie się działanie managera stron. Będzie on dążył do tego by dotknięta strona pojawiła się w normalnej pamięci operacyjnej bo tylko tam instrukcja może być zrealizowana. Czyli wyjdzie nam ze 4 (ona odpowiada 1 w procesie B) trzeba zastąpić strona 0,1,2 lub3.

Najpierw zostanie skopiowane A0 do miejsca 6 w obszarze wymiany. I potem w miejsce A0 czyli w miejsce 0 zostanie załadowana strona z obszaru wymiany czyli strona B1. Na koniec musi zostać zmodyfikowana tablica TTS. Wtedy będzie udostępniona strona logiczna nr1 w procesie B.

Gdy w pamięci operacyjnej są wolne strony, to możliwy jest tylko odczyt (chyba z obszaru wymiany).

Dostęp do strony która jest w pamięci operacyjnej to jest to rząd czasowy mniejszy niż nanosekundym, a jeśli chodzi o dostęp do pamięci której nie ma, która trzeba ściągną z obszaru wymiany to operacja ta może trwać znacznie dłużej, szczególnie jeśli dojdzie do tego konieczność wyrzucenia strony.

Mechanizm stronicowania na żądanie wprowadza zamęt w naszej nomenklaturze bo do tej pory mieliśmy tylko instrukcje obliczeniowe i instrukcje wejścia wyjścia, a teraz operacja każda może wywołać operacje dyskowa , ale taka która nie jest bezpośrednio zamówiona przez proces tylko przez zarządcę systemu. Oznacza to ze nasze programy mogą zmieniać tempo działania nie tylko na skutek obciążenia przez inne procesy ale na skutek za małej pamięci operacyjnej. Im mniej błędów stron, tym nasze programy wykonują się szybciej.

Czy systemy operacyjne różnią się w kwestii pamięci wirtualnej. Dostęp do strony w pamięci operacyjnej to jest zawsze tak samo,.Jeśli chodzi o stronę której w tej pamięci nie ma , ale jest w pamięci miejsce by ją wprowadzić, to też będzie zawsze tak samo. Różnica polega na odpowiednim wyborze strony która ma być wyrzucona gdy tego miejsca w pamięci operacyjnej nie ma. To jest jedyna możliwość tego by poszczególne podsystemy się od siebie różniły.

Sposób wyboru odpowiedniego kandydata do wyrzucenia do pamięci masowej, do pliku wymiany

Zależeć nam będzie przede wszystkim na jak najmniejszej ilości błędów strony.

Algorytm FIFOStosowany w windowsach 9xWyrzucamy tą stronę, która najdłużej przebywa w pamięci operacyjnej. Wydaje się to sensowne ze niby strona która przebywa najdłużej pewnie już nie będzie wykorzystywana, ale to błędne myślenie, bo ta strona może tak naprawdę być bardzo ważna.Algorytm ten doprowadza do sytuacji nazywanej jako szamotanie, tj strona która przebywa najdłużej jest notorycznie wyrzucana do pamięci masowej. Ekstremalny przykład – zapotrzebowanie przekracza możliwości dwukrotnie.

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

7 7 7 2 2 2 2 4 4 4 0 0 0 0 0 0 0 7 7 7

0 0 0 0 3 3 3 2 2 2 2 2 1 1 1 1 1 0 0

1 1 1 1 0 0 0 3 3 3 3 2 2 2 2 2 2 1

B B B B B B B B B B B B B B B

Page 30: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 30

W pionie od góry do dołu mamy strony fizyczne, a w poziomie od lewej do prawej jest ciąg kolejnych odwołań do stron logicznychPierwszy wiersz to wygenerowany przez pewien fragment kodu ciąg odwołań do pamięci operacyjnej chyba. Są tu często odwołania do strony zerowej, może tu jest kod naszego programu. Też często pojawiają się odwołania do strony trzeciej, może tam jest stos naszego programu. Zauważmy, że różnych odwołań do stron logicznych jest dwa razy więcej niż pamięci operacyjnej, zapotrzebowanie tego fragmentu programu na pamięć operacyjną to 6 stron (0,1,2,3,4,57) a dostępne są tylko 3. Zatem będzie tu pewnie ciągły błąd strony, czego nie będziemy dotykać, to tego nie będzie.

Może w pamięci był najpierw inny proces gdy zaczęliśmy ten proces, to by wymagało stronicowania wstępnego czyli wyrzucenia z pamięci stron tego procesu by dać je naszemu. Zawsze jak włączymy nero to bez względu co jeszcze będziemy chcieli włączyć, to będzie miało miejsce stronicowanie wstępne.

Alt+tab przełączanie między procesami ;)

Ostatnia linijka mówi nam o błędach, najpierw nastąpią błędy w czasie stronicowania wstępnego, pamięć operacyjna będzie zapełniona przez strony na które zamieniliśmy kontekst. Czyli najpierw jest w pamięci tylko strona 7, potem jest strona 7 i 0 (akurat te bo taka jest kolejność w pierwszym wierszu), potem jest strona 7,0,1 no ale chcemy się dostać do kolejnej strony bo potrzebujemy dostać się do 2, wiec zostanie wyrzucona 7 itd. Zawsze wyrzucamy tą stronę, która ma najdłuższy staż w RZĘDZIE. Czyli jeszcze raz – pierwszy wiersz to te strony do których będę potrzebowała się odwołać, kolejne trzy wiersze to strony fizyczne, tylko tyle mamy, a ostatni wiersz to wiersz błędów.

Najfajniej byłoby zastępować tą stronę, która najdłużej nie będzie potrzebna. Zatem ten algorytm jest nierealizowalny, bo jak mamy niby ocenić która strona najpóźniej będzie potrzebna to y wymagało analizy kodu który wykona się w przyszłości pewnie lepiej by się ten kod po prostu wykonał, wyglądałoby to tak: (niemożliwy algorytm optymalny)

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

7 7 7 2 2 2 2 2 2 2 2 2 2 2 2 2 2 7 7 7

0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0

1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1

B B B B B B B B B

Czyli teraz wyszło 9 odwołań na 20, a wcześniej 15 na 20, jest więc o co walczyć.

Anomalia Belady`ego

Przykład:proces potrzebuje 5 stron w systemie są 21 2 3 4 1 2 5 1 2 3 4 51 1 1 4 4 4 5 5 5 5 5 5

2 2 2 1 1 1 1 1 3 3 33 3 3 2 2 2 2 2 4 4

B B B B B B B B B

9 błędów na 12 możliwych

Ad tego co wyżej. Najpierw znów zakładamy, że jakiś program tam jest wiec musimy go wyrzucić z pamięci operacyjnej. Porządkujemy najpierw wg algorytmu fifo. Jak dołożymy pamięci operacyjnej to intuicyjnie liczba błędów powinna zmaleć. Zapotrzebowanie tego procesu to 5 stron, powyżej mieliśmy 3 storn, teraz dołożymy jedną, bo gdybyśmy dołożyli dwie to już praktycznie byłoby ok.

Page 31: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 31

i to samo po dodaniu jednej strony:

1 2 3 4 1 2 5 1 2 3 4 51 1 1 1 1 1 5 5 5 5 4 4

2 2 2 2 2 2 1 1 1 1 53 3 3 3 3 3 2 2 2 2

4 4 4 4 4 4 3 3 3B B B B B B B B B B10 Błędów strony na 12 możliwych.

Algorytm ten może być stosowany tylko w specjalnych warunkach – stacje robocze i przy strategii, że rozpoczęcie pracy przez mechanizm stronicowania na żądanie jest sygnałem dla użytkownika, by może zmniejszył ilość puszczonych programów.

Algorytm LRU (least Recently used)Czyli będziemy wyrzucać stronę, która najdawniej była używana.

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

7 7 7 2 2 2 2 4 4 4 0 0 0 1 1 1 1 1 1 1

0 0 0 0 0 0 0 0 3 3 3 3 3 0 0 0 0 0 0

1 1 1 3 3 3 2 2 2 2 2 2 2 2 2 7 7 7

B B B B B B B B B B B B

Czyli początek jest ten sam. W czwartej kolumnie najwcześniej byłą użyta siódma, bo ona była potrzebna jako pierwsza, dlatego ją wyrzucamy.Wyszło 12 na 20 czyli pomiędzy tym co wcześniej,. No i jest ten algorytm wolny od anomalii Belady’ego. Problem: kiedy musi być zapamiętana informacja na temat czasu jej użycia? W Fifo było tak, że jak wprowadzamy stronę to wprowadzamy licznik w otoczeniu tej strony, byśmy wiedzieli która jest najdłużej w pamięci. Natomiast w przypadku LRU chodzi o użycie a nie o wprowadzenie do pamięci, oznacza to, że z każdym dostępem do strony musimy zapamiętać w pamięci operacyjnej może czas logiczny tego zdarzenia. A w FIFo tylko gdy wprowadzaliśmy ja do pamięci. Wprowadzenie do pamięci jest bardzo długi bo to operacja dyskowa, a wiec dorzucenie do tego jeszcze drobnych danych w fifo nie jest to obciążające a w przypadku LRu na każda instrukcje przypadałoby kilkanaście instrukcji zapamiętujących czas logiczny tego wydarzenia i to bez względu na to cyz nastąpiło Stronnicowanie cyz nie. Może to robić sprzet bez utraty zybkosci przetwarzania albo RLU jest niewdrazalny z innych powodow niż algorytm optymalny. Po prostu ten by generowała duze straty gdyby miał być generowany przez zwykłe instrukcje procesora. Procesory nie mają tutaj wsparcia do tego problemu.

Algorytm bitów odniesienia

Zaimplementowany w systemach uniksowych i w uproszczonej wersji w windowsie NT. Procesor Intela jest w stanie zaznaczyć sobie stronę która została użyta, to taki stały znacznik, jesteśmy w stanie czytać, gromadzić te znaczniki. Zatem co jakiś czas zbieramy znaczniki użycia poszczególnych stron i je jednocześnie zerujemy. Czyli gromadzimy historię użycia poszczególnych stron. Wiec dokonujemy analizy nie tego, kiedy dokładnie strona byłą użyta, ale analizy częstości jej użycia, przeglądać. Czyli taki system czasowego przeglądu Pameli wirtualnej możemy sobie zrobić.

Page 32: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 32

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 17 000X 100 10 0016 000 000 00 0005 000 000 00 0004 000 000 X 00 0103 000 000 X 00 X X 1102 000 X 100 10X 1011 000 X 100 10 0010 000 X 100X X 10 X 111

Powiedzmy, ze każda strona ma swój trzybitowy tzw. Rejestr przesunięć – wpisujemy tam wartość bitów odniesienia przesuwając stare bity do tyłu. X – tam była użyta stronaZnacznik użycia trafia na pozycje najstarszego bitu. Tam gdzie strony nie zostały użyte to mamy zero. Zaznaczamy x tam gdzie strona została wywołana względem rzędu cyfr nad tabelą. To wszystko nam mówi, co było używane jak często i kiedy ostatnio. Można odczytać te liczby dziesiętnie. Wybieramy tą ,która ma najmniejszy licznik przesunięć. Najważniejsze jest to, że te operacje zbierania statystyk nie musimy wykonywać co każdą instrukcję, tylko co grupę instrukcji, bo jednak system i tak musi co jakiś czas organizować wszystko w związku z szeregowaniem chociażby. Strona może uchronić się od wyrzucenia tym, że ostatnio była w pamięci używana. Jeśli wszystkie strony przedstawią coś takiego, to wykorzystany będzie algorytm FIFO, ale nadal tu już nie będzie anomalii Belady’ego. On musi trochę popracować nim stanie się porównywalny z LRU. Można go nazwać least frequently used.

Zarządzanie pamięcią masową

Przechowywanie informacji w miejscach, które mają trwałość systemową, tj taką, która zostaje nawet po wyłączeniu systemu, to główny czynnik odróżniający pamięć masową od pamięci operacyjnej. Hibernacja to zrzut pamięci operacyjnej do pamięci masowej i potem powrót. Pamięć masowa to tablica bajtów, mniejsza o to jak indeksowana.

W jaki sposób na urządzeniach pamięci masowej zapisywana jest informacja (głównie chodzi o dyski) na temat tego co jest wolne a co jest zajęte? Jakie obszary dysku mogą być zaalokowane na potrzeby nowej informacji. Nie ważne w jaki sposób są zajęte, czy przez pliki czy informacje systemowe.

Mapa bitowa to ona odpowiada za powyższe. Dysk dzielony jest na obszary o tym samym rozmiarze i każdemu obszarowi odpowiada bit który jest elementem mapy bitowej i ten bit ma wartość która mówi ,czy ten obszar jest zajęty czy nie. Pytanie jakiej wielkości jest mapa bitowa, to zależy od tego jak duży jest blok na który dzielimy dysk. Podział dysku na bloki jest zwykle nieunikniony, większość interfejsu nie działa na pojedynczych bajtach tylko na większych jednostkach danych. Zwykle jak chcemy odczytać jeden bajt ,to wciągamy tak naprawdę 512 bajtów i wybieramy ten bajt który nas interesuje, to jest zwykle najmniejsza jednostka transferu danych, jest to dość mało. Gdyby to było tak zawsze, to dysk 500giga miałby 1giga tych obszarów, co jest mało fajne, szczególnie pod kątem numeracji. Dlatego agregujemy te małe bloczki, nie stosujemy jednostki typu 512bajtów tylko jednostkę 4kb, co ładnie pasuje do stronicowania, haszowania w procesorze itp. Można próbować też większych jednostek, ale zawsze mapa bitowa jakaś tam wyjdzie. Jak mamy dysk 512giga i 4kb na blok, to tych bloków wyszłoby 128Mega i gdybyśmy z tego chcieli ulepić mapę bitową, to wychodzi, że minimalny rozmiar mapy bitowej to 16Mb. Mapa bitowa też może podlegać mechanizmowi stronicowania.

Jak mamy mapę bitową to jesteśmy w stanie szybko sprawdzić ile jest wolnego miejsca na dysku a także łatwo znaleźć wolne miejsce na alokację,. Jesteśmy w stanie też w

Page 33: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 33

łatwy sposób zwalniać miejsce. Mapa bitowa implikuje fragmentację wewnętrzną. Może się też zdarzyć niedopełnianie bitów do końca, to kiedyś było problemem (system Windows 95 zadebiutował na systemie plików FAT16 pochodzącym z DOS, maksymalna wielkość przestrzeni dyskowej obsługiwanej były 2giga i to tylko i wyłącznie przy jednostce alokacji 32kb, rok później Microsoft wypuścił odpowiednik servicepacka tylko pod inną nazwą, takie poprawki i tam było wprowadzenie FAT32, pozwala on na zmniejszenie bloku dyskowego y 32kb na dowolną wielkość, a zalecana była 4kb. Na tych 2 giga zyskano 20-30% dysku. To na pewno jest coś. Skąd takie duże zyski? Otóż większość informacji przechowywana jest w bardzo małych plikach na dysku, mają one kilka, kilkanaście , kilkadziesiąt bajtów i jest bardzo dużo takich plików na dysku w porównaniu do tych dużych.

Subalokacja było to jedno z dawnych rozwiązań tego problemy, że mamy te nasze kawałki dysku a w każdym z nich jest malutko danych. Dlatego gromadzimy informacje zwykle w dużych blokach dyskowych, a końcówki plików lub małe pliki będziemy gromadzić w innym miejscu, która będzie blokiem np. 512bajtowym, przez co ograniczona zostanie wewnętrzna fragmentacja. Działało to zwykle asynchronicznie jakoś nocą itp. Ale był kłopot wtedy z zarządzaniem. Zyski jednak wcale nie były aż tak duże, a poza tym stopień skomplikowania takiego systemu i jego podatność na awarie, że sobie odpuszczono.

Teraz raczej nie szalejemy z wielkością bloku dyskowego. Jak sobie zrobimy plik z notatnika i wpiszemy tam jedną literkę, to napisze ze rozmiar jest 1b a poniżej we właściwościach że zajmowany rozmiar na dysku to 4bajty.

Alternatywa dla mapy bitowej czyli inny system plikowy, który nie cierpi na wewnętrzną fragmentację z dokładnością do rozmiaru minimalnego bloku transferu.

Lista powiązań

Można założyć, że system zapamiętuje gdzieś informacje tylko o pierwszym bloku wolnym i zapisuje to w postaci pary: adres, długość. Na końcu pierwszego kawałka jest zapisywana podobna para, która identyfikuje następny wolny blok i jego długość itd. Na końcu NULL. Jeśli w obszarach wolnych jest zapisywana jakaś informacja (ta nasza para liczb) to niby nie są wolne, ale jak zacznie być tam coś zapisywane to po prostu nadpisze tą naszą informację, bo to już nie będzie obszar wolny, więc nie będzie ona potrzebna. Adresy mogą być wyrażone w najmniejszych jednostkach alokacji. W mapie bitowej była zależność od rozmiaru dysku a tu nie. Jednak tu jest trudniej zarządzać, trzeba buforować wciąż wskaźniki poza tym wydajność pracy tego modelu i to w jaki sposób angażuje zasoby naszego kompa głównie pamięć operacyjną jest zależne od tego jaki jest stopień uspójnienia informacji zapisanej na dysku. W sytuacji najlepszej owa lista składa się z jednego elementu, a w najgorszym jest tak, gdy co drugi blok jest zajęty, a co drugi wolny, wtedy rozmiar tej listy jest bardzo duży. Czyli wydajność się waha i może ewentualnie być znacznie gorsza niż w mapie bitowej. W komputerach zwykle używa się koncepcji mapy bitowej. Ogólnie więc nie warto zajmować się tą listą.

Koniec odróżniania bloków wolnych i zajętych.

Pytanie jak dzielić obszar zajęty na poszczególne fragmenty spójne na poziomie logicznym zwane plikami. Zaproponujemy 3 modele przechowywania tej informacji:

Page 34: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 34

Przydział miejsca na dysku (odwzorowania plikowe)

Przydział ciągły

Stosowany w specyficznych urządzeniach. Dane potrzebne do zlokalizowania pliku to: adres pierwszego bajtu pliku oraz długość pliku. Dodatkową przesłanką jest fakt, że każdy plik zajmuje kolejne jednostki alokacji. Oznacza to, że jeżeli część pliku znajduje się w pewnym bloku dyskowym, to by przeczytać kolejny fragment pliku, trzeba przeczytać kolejny blok dyskowy.

Zalety:- ekstremalnie mała liczba informacji zapisywanych z każdym plikiem (bo tylko dwie liczby)- zwykle urządzenia lubią jak się je czyta po kolei

Wady:- kłopot ze znalezieniem miejsca dla nowego pliku. Jak na dysku zapiszemy pierwszy plik, a potem będziemy chcieli zapisać drugi plik to nie wiadomo gdzie, bo jeśli zapiszemy tużza pierwszym, to pierwszy nie będzie mógł wtedy się powiększać, bo przecież musi być sekwencyjność. Ten sposób rozpraszania informacji tj. zostawianie trochę miejsca za końcem każdego pliku nie jest głupi o tyle, bo sprzyja spójności. Niektóre systemy przenoszą plik w miejsce, gdzie rosnąć może, ale jeśli jest ten plik duży, to przeniesienie go wcale nie jest takie proste. Mechanizm zachowywania spójności plikowej może być tylko wspomagający, ale do faktycznego zastosowania to taki system gdzie jest odgórne założenie ze wszystkie liki są spójne jest możliwy tylko przy określonym typie przechowywania danych, czyli takich gdzie pliki nie będą rosnąć. Np. na CD. Tam jak tworzymy płytę CD czyli mamy nośnik write once, read many, to pliki mają ustaloną wielkość i nie będą rosły, ustawiamy więc pliki jeden za drugim, a info o tym gdzie te pliki się zajmują będzie zapisana w postaci pary bajtów, którą tablicujemy. CD bardzo lubią jak się je czyta po kolei. Posobnie ze streamerami – napędy taśmowe, służyły do robienia archiwum, tyle że potem i tka był kłopot by odzyskać te dane, ale co tam.

Przydział listowy

Obecny we wszystkich systemach poza uniksowymi. Dla każdego pliku zapisujemy informacje o adresie jego pierwszego bajtu lub pierwszego bloku oraz jego długości. Dodatkowo dla każdego bloku zajmowanego przez plik zapamiętujemy informacje o położeniu następnego po nim bloku. Czyli dwie pierwsze informacje są takie jak w przydziale ciągłym. Kłopotliwe jest jak mamy zapamiętywać adres następnego bloku. W kompach 8bitowych było takie rozwiązanie, że jak mamy prostokąt który utożsamiamy z dyskiem twardym na którym jest szachownica i ponumerowane jest jak w szachach że A1 itp. Każdy blok może być wolny lub zajęty i zapamiętuje informacje o tym, gdzie znajduje się blok następny. Jeśli mamy plik którego pierwszy kawałek jest w miejscu C2 to na koniec tego bloku jest referencja na kolejny. To dokładne odwzorowanie listy jednokierunkowej której elementem jest blok dyskowy. To było stosowane w systemie CP/M wada: mieszają się dane i informacje o charakterze dyskowym w jednym bloku. Wtedy gdy chcemy coś usunąć, to musimy przeczytać cały blok, by dojść do różka. Zrobiono tak, że te różki, te wskaźniki wyjęto i wsadzono do innego miejsca. Tak powstały wydania FAT, czyli ta tablica następstw.

FAT Final Allocation Table

Dysk dzieli się wiec na dwie części pierwsza to wskaźniki, czyli mapa reszty dysku tyle ze nie jest to mapa bitowa a mapa złożona z adresów. Za tym FATem znajdują się pliki dyskowe. Komórka FATu to mało info a poniżej dużo info. W plikach dyskowych przechowujemy tylko fragmenty odpowiednich plików. Czyli tak jak na początku mieliśmy

Page 35: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 35

jedną tablicę z różkami, tak teraz mamy najpierw taką małą tablicę z FATem a potem pod nią odpowiednią dużą tablicę.

FAT z punktu widzenia przechowywana info na temat zajętości. Zauważmy, ze FAT nie potrzebuje dodatkowego wsparcia. W pozostałych kratkach możemy wprowadzić symbol odpowiadający blokowi wolnemu. Zwykle same 1 to EOF a same 0 to blok wolny. EOF to ostatni blok dyskowy prawdopodobnie niepełny, ale jednak zajęty. Jak plik ma tylko jeden blok dyskowy w którym jest EOF to znaczy ze to jest bardzo mały plik, którego blok jest jednocześnie pierwszym i ostatnim. Pytanie czy tracimy miejsce jeśli zapisujemy pliki o zerowym rozmiarze u mnie na kompie nie, nie ma potrzeby dokonywania żadne alokacji, pole o pierwszym adresie pozostaje niewypełniony.

Rozmiar FATu. To informacja o klasie ważności jeszcze wyższej niż mapa bitowa. Powiedzmy, że mamy nasze 512GB dysk. Ustaliliśmy, że wtedy rozmiar bloku to 4kb i mamy 128mega bloków dyskowych. FAT zależy od sposobu adresowania jaki przyjmiemy. Musimy odwzorować 128M (128 milionów) bloków dyskowych, więc jedno odwzorowanie jest takie duże jak jeden adres, możemy zanumerować to za pomocą liczby 32bitowej, a 16bitowej nie, tylko każdej większej. Zatem 1 adres w FAcie zajmie 4 bajty przy 32bitowej numeracji. Zatem 128M x 4b = 512MB, czyli wyszedł jeden informatyczny promil ;) FAT musi być replikowany i zachowane info dodatkowe z katalogami związane i info do zarządzania to nadal możemy sobie to darować i jest dobrze. My te bloki FATu możemy przechowywać na dysku w postaci spójnej. Możemy robić FATy transakcyjne przechowujące info o kasacji plików. Wtedy łatwo odzyskać skasowany plik, co ważne w stosunku do przydziału indeksowego. Kosz w Windowsach to aplikacyjna ściema, to przenoszenie plików do innego folderu. Możemy mieć obiekcje co do buforowania tego obszaru, ale nie ma potrzeby się tego bać, bo zwykle jest tu stronicowanie, wiec w ekstremalnej sytuacji jesteśmy w stanie odwzorować w pamięci cały FAT. Jak system startuje to wciąga masę info do pamięci i potem metodą stronicowania na żądanie niepotrzebne informacje wypadają. Dlatego działa szybko a zaczyna wolno. Z powodu liczności bloków dyskowych zaczynamy mieć kłopot z adresowaniem, bo przy odpowiednio dużym dysku to 32bitowe adresowanie może nie wystarczyć np. dysk 32 razy większy niż 512 to FAT32 wysiądzie, choć prawdopodobnie wysypie się już wcześniej. Przejście na FAT64 pewnie nie będzie głupim rozwiązaniem skoro pamięci masowe tak szybko rosną.

W FAT16 bloków dyskowych nie mogło być więcej niż 64k, a z drugiej strony blok dyskowy musiał się mieścić w segmencie danych architekturze procesora 86 dlatego nie mógł być bardzo duży, wiec przyjęto, że jeden blok dyskowy nie może być większy niż 32kb, a już to bardzo dużo. Zatem 32 x 64 = 2^11 MB, czyli 2 giga to maksymalne górne ograniczenie partycji dyskowej.

Page 36: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 36

Pliki skrzyżowane

Jeśli były to dwa filmy, to mają wspólne zakończenie. A B C D E

B5(beta1) EOF(beta4,alf4)B2(gamma1) B4(gama2) C3(ksi1) E2 D4C5(delta1) C4(alfa1) D3(ksi2) Eof(ksi4) D1(alfa3,beta3)

D5(gama3,5,7) E3(alfa2) E4 E5E3(beta2) C6(delta2) B4(gama4,6,8) Eof

Katalog urządzeniaNazwa pliku pierwszy blokAlfa B3Beta C1Gana A2Delta A3Ksi C2

Możliwe do podjęcia kroki naprawcze- możemy sformatować dysk czyli wyzerować FAT- możemy usunąć oba pliki, które się skrzyżowały, nie wolno jednego z nich, można też usunąć ten fragment krzyżujący się, ale trzymamy się tego by uniknąć usuwania dużej ilości danych. Powinniśmy rozkrzyżować te pliki prze duplikacje powtarzających się końcówek. Jeśli oba pliki maja wspólne koniec składające się z e3 i d1 to w obszarze danych trzeba skopiować te dane do nowych pustych bloków i zmienić adresacje jednego z tych plików tak by zaadresować te pliki.

Zauważmy, że mamy gamma plik zapętlony sam ze sobą.Liczba znaczników eof jest mniejsza niż liczba plików i po tym można stwierdzić tą sytuację. Sensownym krokiem naprawczym jest obcięcie pliku do miejsca zapętlenia, jest to mniej groźne niż pliki skrzyżowane. Powinniśmy w D5 wstawić eof i zmodyfikować długość pliku.

Zła koordynataPrzykład delta.

Błędny rozmiarPrzykład ksi. Może się zdarzyć, że w katalogu urządzenia wielkość jest bardzo inna niż być powinna, czyli informacja ta jest niezgodna z informacja o długości pliku wynikająca z fatu. Wtedy powinniśmy przyjąć dane z FATu, a nie z katalogu urządzenia. Jeżeli długość pliku jest krótsza niż to co wynika z FATu należy go przedłużyć w katalogu urządzenia by nie utracić danych. Jeśli jest większa, to i tak nie wiemy, które pliki dyskowe mielibyśmy dołączyć by zwiększyć długość, nie możemy przyłączać dodatkowych plików dyskowych losowych. Powinniśmy go w katalogu skrócić do tego, co jest napisane w FATcie. Czyli to FAT decyduje o wielkości plików w przypadku konfliktu.

Zagubione łańcuchyMoże się zdarzyć tak, ze w FATcie jesteśmy w stanie wyróżnić pewien łańcuch następstwa, który nie ma odpowiedniego wpisu w katalogu urządzenia. To to bez literek ksi itp. Powinniśmy wyłuskać najdłuższe takie łańcuchy i nadać im nazwy inne niż istniejące klucze, czyli chcemy po prostu go nazwać. Łańcuchy te nie są niebezpieczne, one tylko zabierają nam miejsce na dysku. Gdy zamienimy na pliki taki łańcuch to znów utracimy częściowo info związane z długością pliku, bo plik będzie miał taką długość, jaka jest spowodowana ilością wpisów. Problem: możemy obrócić ten zgubiony łańcuch na plik dłuższy niż pierwotny, więc pytani czy nie dołączyliśmy do pliku znów informacji poufnej, dlatego takie odzyskanie powinno być pod kierownictwem administratora.

Page 37: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 37

Koniec jeśli chodzi o przedział listowy. Inny sposób przydziału miejsca na dysku to:

Przydział indeksowyZaczynało się od Unixa, dla którego nazwa pliku wcale nie była taka ważna, tam był ważny numer pliku, każdy miał inny i własny, nazwa była tworem wtórnym, to i-węzeł (i-node) identyfikował plik. To on zawierał wszystkie informacje o pliku poza jego nazwą. Tabele odwzorowujące tabele i-węzłow na nazwy to katalogi, czyli specjalne pliki które możemy sobie wyobrazić jako proste tabele. Z faktu takiej konstrukcji wynikają szczególne cechy takie jak: jest możliwe w odróżnieniu od innych systemów, by plik rozumiany jako zestaw zapisanych w pamięci masowej informacji był dostępny pod wieloma nazwami. Idea jest taka by w momencie otworzenia pliku cały i wezeł został zbuforowany w pamięci podręcznej, czyli po otworzeniu pliku nie pracujemy na nazwie tylko na i-wezle i jego opisie, bardzo szybko wyłuskujemy wiec informacje o właścicielu, długości i inne takie. Przed otwarciem pliku takie informacje są niedostępne. I-węzeł powinien mieć mały rozmiar i być on stały, powinien umożliwiać bardzo szybkie dotarcie do wszystkich bloków dyskowych zajmowanych przez plik. W sytuacji optymistycznej w i-węzle powinny być adresy wszystkich bloków dyskowych zajmowanych prze plik, ale to by przeczyło temu ze ma być on mały i o stałej wielkości. Rozmiar i-węzła to taka jakby jedna linia ls –l, to te wszystkie informacje poza ostatnią kolumną tj nazwą. Może być rzędu kilkudziesięciu bajtów, a nawet mniej.

Zatem i-węzeł nie może zawierać adresów wszystkich bloków zajmowanych przez plik. Większość informacji odbywa się na plikach, które są krótkie. Przyjęto więc rozwiązanie, że pliki krótkie mają w całości dostępne bloki dyskowe z poziomu i-węzła, a dłuższe mają tak, żę w i-węźle podajemy adres miejsca, w którym są pozostałe dyski zajmowane przez plik.

System BSDObecny we wszystkich systemach unixowych. W oryginalnym system BSD poza informacjami takie jak prawa dostępu, daty ostatniej modyfikacji itp. Było dodatkowo 15 adresów bloków dyskowych, czyli otwierając pliku inaczej buforując i-węzeł w pamięci operacyjnej mieliśmy od razy dostęp do 15stu bloków (ale nie musiały to być pierwsze piętnaście), bo te 15 adresów jest traktowanych specjalnie: 12 pierwszych to adresy bezpośrednie, 12 pierwszych bloków dyskowych pliku. Jak mamy do czynienia z dłuższym plikiem to pierwszy z tych dodatkowych adresów czyli 13 jest adresem bloku pojedynczo pośredniego. Blok pojedynczo pośredni jest tablicą dalszych adresów bloków dyskowych pliku. Trzeba przyjąć konkretną wielkość adresu i bloku dyskowego. Dla uproszczenia zwykle przyjmujemy, że adres jest 4bajtowy czyli 32bitowy, a blok ma 4kb, czyli w przybliżeniu jesteśmy w stanie obsłużyć pliki do 4Mega. Gdybyśmy wykorzystali adres 14 i 15 tak samo jak 13 to byśmy przedłużyli do 8 i do 12 mega. Wiec robimy to sprytniej. Adres 14 to adres bloku podwójnie pośredniego. Zawiera on adresy, które wskazują na adresy, które dopiero wskazują na bloki w pliku. Za pomocą bloku podwójnie pośredniego dokładamy 1024 w kwadracie adresów bloków dyskowych. Wiec za pomocą bloków podwójnie pośrednich jesteśmy w stanie mieć 4giga. 15 adres to adres bloku potrójnie pośredniego. Dokłada to bloków dyskowych w sześcianie, co daje nam ograniczenie wielkości pliku do 4terabajtów.

Z takiego sposobu organizacji przestrzeni dyskowych wynika:- duże pliki SA dyskryminowane jeśli chodzi o dostęp w porównaniu z małymi plikami, zakłada się ze duże pliki SA najczęściej obsługiwane sekwencyjnie, strat nie ma dużo- jeżeli mamy do czynienia z przedziałem listowym, to mamy elegancką i łatwą do utrzymania strukturę w pierwszej przestrzeni dysku mamy tablice alokacji plików, a w drugiej części mamy …. Wiec operacje naprawcze czy replikowania są łatwe, znajdują się te wszystkie informacje w jednym miejscu, natomiast tutaj z dynamicznie przydzielanych bloków dyskowych część to SA bloku, które nie zawierają danych pliku, tylko zawierają informacje potrzebne do zlokalizowania danych pliku, wiec wyobraźmy sobie ze nasz dysk ulega częściowemu urządzeniu, to takie momenty zwykle załatwiamy przy pomocy

Page 38: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 38

replikacji, a jeśli tutaj taki obszar wystąpi w obszarze danych to w przedziale listowym będą uszkodzone tylko te pliki, które miały pecha znajdować się w tym właśnie miejscu, zaś w przedziale indeksowym jeśli będzie ona dotyczyć 13 lub 14 lub 15 to automatycznie stracimy daleko więcej informacji, oznacza to, że dla większej pewności systemów plikowych powinniśmy zacząć zwielokrotniać również bloki indeksowe. Powinniśmy również myśleć o tym, by gromadzić je możliwie blisko siebie i replikować całymi grupami. To powoduje, że systemy indeksowe które mają być pewne SA dużo bardziej skomplikowane i podatne na awarie., jedynym faktem, którzy przekonuje do systemu plików z przydziałem indeksowym jest fakt, ze SA wbudowane w unix, ale z punktu widzenia użytkownika maja więcej wad niż zalet, więc pewnie będą hybrydy, ale raczej nie będzie już indeksowych nowych. Dlatego czasami można odzyskać utracony plik w systemie unikowym tylko jeśli jest mniejszy niż 48kb, bo to znaczy ze jesteśmy w stanie odzyskać z jakiejś starej bazy węzłów dane jeśli nikt ich nie nadpisał, a jeśli chodzi o te dalsze to ryzyko uszkodzenia jest na tyle duże, że już się tego nie robi. Wiec odzyskiwanie straconych plików jest znacznie trudniejsze w takich systemach.

Budowa systemu unixowego

Jak budowano i jak jest wreszcie zbudowany tradycyjny system unixowy, czym jest , jakiej taksonomii podlegają te systemy itp. Za tydzień będzie mikrojądro i szczegóły konstrukcyjne rodziny systemów Windows NT.

Co to jest ,kiedy powstał, po co, jalkie były jego główne obszary zastosowań.

Powstał w końcu lat 60tych, protoplastą był Multix który powstał z nudów, napisali go Richie i Thomson. Były prace badawcze prowadzone wcześniej. Multix wdrażał wielozadaniowość w takim sensie jak mówiliśmy o tej wielozadaniowości na początkowych wykładach. Rewolucyjne jeśli chodzi o system unix było samo podejście do jego produkcji. Otóż, równolegle ci dwaj panowie stworzyli język programowania wysokiego poziomu – nasz ukochany C. jeśli chodzi o stopień abstrakcji, to zuniformizowany asembler…w sensie blisko jest od tego języka do procesora. Język c jest asemblerem który jest przenośny. Oznacza to, że możemy się pokusić o to, ze bez utraty funkcjonalności jesteśmy w stanie zakodować w tym języku jakaś większą funkcjonalność no system operacyjny, a te rzeczy których nie da się w nim zaprogramować t napiszemy w języku wewnętrznym (te rzeczy najbardziej unikalne). Zatem jeśli część kodu asemblerowego jest mała, to nasz wysiłek jest niewielki by przetransportować ten fragment na inna maszynie a cała reszta wymaga tylko kompilacji. Zatem jeśli potrzebujemy system łatwo przenaszalny, to musimy zadbać by część asemblerowa była malutka i to się udało zrobić tym panom, mieli tylko 2000 linii asemblerowych, cała resztę napisali w C. Zatem pokazali firmie, że są w stanie łatwo przetransportować ten system na inne maszyny które stały w magazynie, zatem firma stwierdziła, ze jest to cos co warto rozwijać i to było w latach 70tych.

Potem podjęto decyzje, ze ten rozwój będzie nie tylko sprawa wewnętrzną TNT ale też podzielą się tymi pracami badawczymi ze środowiskiem akademickim, najważniejszym był Uniwersytet Kalifornijski Berkeley UCB. To sprawiło rozziew na dwie rodziny, gałęzie, jedna pochodziła z firmy, a druga z uniwersytetu. CO więcej, obie te instytucje prowadziły działalność komercyjną polegającą na odsprzedaży swojego systemu do firm zajmujących się produkcją sprzętu komputerowego. Firma która wyprodukowała jakąś fajna maszynę np. IBM (opartą na procesorze RISCowym) i zapragnęła ją oprogramować za pomocą systemu Unix, zatem zwracała się albo do NTNT albo do uniwerka nabywając ten system i konkretną specyfikację kawałka asemblerowego. Dodawała też na swoje potrzeby swoja funkcjonalność i wychodziła jakaś nowa wersja systemu. Irix wyszedł z tego, firma Sun zrobiła z tego Sunos itd., czyli powstało wiele systemów zbudowanych na bazie Unixa. Były też różne polityki w tych firmach jeśli chodzi o dodawanie własnych elementów . doprowadziło to do pewnego bałaganu na rynku. Jeśli użytkownika jednego

Page 39: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 39

systemu unikowego posadzimy przy innym systemie unikowym, to raczej nie poczuje się on tak jak w domu ;)

Zatem mamy konieczność normalizacji nomenklatury i podstawowych interfejsów systemu, Został więc powołany komitet i to on jest Unixem, nazywa się on POSIX (Portale Operating System Interfejs Unix).Mówi on co powinno być, jakie element, mówi o interfejsie funkcyjnym, jaki jest podstawowy zakres i semantyka funkcji, pewien podzbiór obowiązkowego API. Poza tym POSIX definiuje też zalecane systemy plikowe, zalecane układy katalogów, sposoby pracy podstawowego oprogramowania, np. interpreter Bournea, interfejs gniazdek, czyli podstawowa forma oprogramowania warstwy transportowej sieci. Niestety nie wszystkie systemu unikowe SA zgodne ze specyfikacją POSIX, łatwiej jest też powiedzieć z czym jest zgodny niż w drugą stronę, ale nadal dobrze ze te normy istnieją, bo to gwarantuje, że mniej lub bardziej bezboleśnie jesteśmy w stanie przejść z jednego systemu unixowego na inny. Obecnie to zagmatwane, bo SA obecnie systemu które nie SA Unixem ale są zgodne w dużej mierze ze specyfikacją POSIX. Np. jest to Linux, jądro tego systemu nie pochodzi ani z NTNT ani z Berkely. Nie pojawiają się tak często jak kiedyś nowe sprzęty, w senesie łatwiej jest przenosic to co jest. Świat jest niejako opanowany przez procesory Intel i to co jest z nimi kompatybilne, czyli zapotrzebowanie na przenośność systemu operacyjnego znacznie zmalała, niby nadal jest rynek dużych maszyn, ale tu też już jest inaczej niż dawniej. Jest coraz mniej różnorodności, raczej jest więcej ujednolicania, dlatego teraz rodzi się mało nowych Unixów, raczej wykorzystywane są dostępne kody takich systemów jak berkelejowski czy linux do konstrukcji zamkniętych całości. Klasycznym przykładem jest system w któryt wyposażony jest komputer Apple czyli MacOS. Środowisko Darwin jest zbudowany na FreeBSB który jest szwagrem pewnej linii systemu Berkeljowskiego którego produkcja skończyła się w 84 roku i potem była już tylko rozwijana prze wolontariat internetowy.

Mamy też schyłkową taksonomię systemów unikowych która akcentuje to skąd pochodzi dany system (czy jakoś tak…). W sensie możemy się spotkać z określeniami System V to była bzowa wersja finalna wyprodukowana przez NTNT i BSD – ta od berkelejowskiego. No i możemy się dowiedzieć, że dana wersja należy do systemu BSD lub tego drugiego. Przynależność do tych rodzin systemowych jest charakterystyczna, bo System V jest wyposażony w funkcje których ten drugi nie ma, ale tak naprawdę obecnie jest to nieaktualne, raczej starają się by dany system miał rzeczy charakterystyczne z obu tych rodzin. Sanos (Sunos?) zaczęła od BSD, ale funkcjonalność Systemu V też w tym jest, czyli ogólnie to sprawa historyczna, zostały może jakieś ślady, ale to są drobiazgi takie jak klasyczny system startu, różnice na poziomie aplikacyjnym, kwestia wymiany jednej aplikacji.

Ciężko wiec powiedzieć czym Unix jest i czym nie jest.

Cechy systemu Unix:

Cecha 1 Jądro systemu oprócz pewnej ściśle związanej ze sprzętem części jest napisane w języku C (z tego nie wynika nic na temat działalności tego systemu, ale warto to zaobserwować w kontekście przenośności między platformowej). Większość tradycyjnych systemów unikowych to systemy oparte o tzw. jadro monolityczne, co oznacza, że jądro jest jedynym programem, który pracuje w przestrzeni uprzywilejowanej, wszystkie pozostałe aplikacje komunikują się z ją drem poprzez mechanizm przerwań. Czyli jądro wykonuje operacje a potem prawo dostępu wraca do programu który zamówił operacje.

Zyski: stabilność, bo jeśli oprogramowanie pracuje w warstwie uprzywilejowanej jest oprogramowaniem wysokiego stopnia zaufania (czyli jest lepszym w senesie jakości niż to co jest na poziomie nieuprzywilejowany,) to pewnie jakakolwiek funkcjonalność nie wpłynie na stabilność tego co jest na poziomie nieuprzywilejowanym,, czyli programy nie

Page 40: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 40

będą sobie robiły wzajemnie krzywdy, chyba ze znajda słaby punkt systemu. Wszystko przechodzi więc przez system operacyjny, jakakolwiek funkcjonalność wykonywana prze użytkownika, to co jest uruchamiane na początku itp. Walidacja do zasobów sprzętowych – kosztem tego jest wydajność, gdyby to było wprost, to wydajność byłaby większa, ale wtedy nie byłoby stabilności.

Wady: na gorąco system nie jest w stanie zmieniać swojej funkcjonalności. To może być w konflikcie z tym co wiemy o Linuxie, ale tam jest coś o modułowości, to jest trochę mniej niż ta odwrotność do monolityczności. Nie jesteśmy ta naprawdę w stanie zrobić nic poza dołączeniem do istniejących // system operacyjny musi mieć stworzone miejsca // prowadzący stracił wątek ;)

Jądro ma jakiś punkt styku i ten punkt działa tak, eę przez zainicjowany punkt styku mogą przepływać dane z innych części jądra. Dołączenie pewnej funkcjonalności jądra to rozszerzenie obszaru adresowego jądra o pewien kod który może przechwytywać ta transmisję danych. W systemach, które oparte SA na mikrojądrze, czyli tych, które SA w opozycji do tych z jądrem monolitycznym możemy zrobić inaczej, mianowicie w obszarze uprzywilejowanym możemy uruchomić proces, który jednocześnie ma bezpośredni dostęp d o zasobów sprzętowych i jednocześnie potrafi komunikować się z jądrem systemu przez pewien interfejs komunikacyjny, który jest analogiczny do innych systemów komunikacyjnych działających na tej samemu platformie. Czyli niby różnica nie jest duża, ale kod dołączany do jądra monolitycznego musi mieć ściśle określoną funkcjonalność czyli ściśle określone wejście i wyjście. Czyli rozwijać możemy tylko to, co już w jądrze jest. Jeśli jądro umie obsługiwać abstrakcyjną kartę sieciową, to możemy dołączyć na gorąco coś do obsługi konkretnej karty sieciowej.Nie jesteśmy w stanie rozszerzać API systemu. Jeśli chodzi o podłączanie np. USB to jest to coś, co ma interfejs uniwersalny i tu nie ma problemu zarówno w mikrojądrze jak i w jądrze monolitycznym. (doładowujemy moduł który z uniwersalnego interfejsu zrobi interfejs szczegółowy związany z tym jednym urządzeniem i nie wymaga to przebudowania API systemu, a w tym drugim powiększa się skala możliwych do wywołania funkcji). Na jądrze monolitycznym jest linux.

OSP/1 np. jest jednak oparte na mikrojądrze, czyli my sami możemy określać, co nasz system będzie serwował. Analogicznie z QNX – typowy przedstawiciel systemów unikowych do wspomagania pracy w reżimie czasu rzeczywistego(wykorzystywany w automatyce przemysłowej itp.) Na mikrojądrze jest też zbudowany Windows NT mimo że pochodzi z czegoś co było na jądrze monolitycznym, ale o tym będzie za tydzień.

Tyle o jądrze. Jest ono czymś, co najbardziej pasuje do nazwy Unix, ale jądro to nie wszystko, bo nad nim startuje zestaw oprogramownaia użytkowego.

Jądro oferuje:

Cecha 2:-system wielozadaniowy z podziałem czasu preferujący zadania nastawione na wejście wyjście kosztem zadań obliczeniowych. Realizacja tego może być na wiele sposobów, najpopularniejszym np. w Linux jest algorytm średniej ważonej przedstawiony gdzieś w pierwszej połowie semestru, ale np w QNX jest to algorytm kolejek wielopoziomowych.

Jakie było wobec tego planowane zastosowanie tego systemu?Unix nie był planowany jako system serwerowy tylko jako oprogramowanie dla systemów jednoprocesorowych i dla systemów końcowych czyli dla stacji roboczych,. Mimo wszystko podjęto decyzję ze będzie priorytetowa zadania nastawione na wyjście wejście, dlatego się dobrze sprawdzają w zastosowaniach systemowych. Thomson myśleli o tym, że gdy użytkownik puszcza cos na swoich stacjach roboczych to by mógł też coś delikatnego na boczku puścić o to im chodziło.

Page 41: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 41

Cecha 3Jednostka aktywna w systemie to proces, pracujący w trybie nieuprzywilejowanym w wydzielonej przestrzeni adresowej. Chodził o ot by każdy proces widział system jako własny, cały do jego dyspozycji. Jeżeli jest kontakt z innymi procesami to pośrednikiem jet jądro systemu, ale przestrzenie adresowe nie zachodzą na siebie co daje stabilność i brak niekorzystnych interakcji, a wada jest taka, ze komunikacja może być utrudniona, nie da się przepisywać pamięci bo nie ma wspólnej pamięci. To jednak nie jest aktualne w większości systemów unikowych. Wiele systemów obecnie aplikuje mechanizm wątków na poziomie jądra, co odwraca spojrzenie nasze na elementu aktywne, wtedy proces jest elementem biernym, w ramach jego może być wiele wątków, musi być przynajmniej jeden, to jest obce Unixowi.

Cecha 4Unix używa pamięci wirtualnej, rozszerzenie pamięci operacyjnej jest praktykowane zwykle w pamięci masowej. Czyli jeśli na jakimś systemie sprzętowym chcemy zaadoptować system unixow, to musimy zobaczyć czy jest jakieś wsparcie pamięci wirtualnej typu segmentacja, czy Stronnicowanie na żądanie, dopiero jeśli to jest ,to możemy aplikować tam system unikowy, bo to wiąże się m.in. z tym, że pliki wykonywalne w systemie unix wiążą adresy w trakcie kompilacji, to one decydują jak ma wyglądać ich przestrzeń adresowa numerycznie, czyli ta przestrzeń musi być wirtualna, nie może być dokładnym odwzorowaniem pamięci operacyjnej naszego komputera. Czyli chodzi o to by adresy były logiczne a nie fizyczne, jedyne co ma dostęp do fizycznego adresowania pamięci jest jądro.

Literówki spowodowane są Wordem.

Cecha 5Wbudowana jest następująca cecha: niewykorzystywana pamięć operacyjna jest używana jako bufory otwartych plików. To optymalizuje pracę, liczbę operacji,(operacje na pamięci i opóźnione operacje wejścia wyjścia), zatem zwykle system unikowy nie ma wolnej pamięci operacyjnej. Duże wykorzystanie pamięci prze normalna działalność systemowa może skutkować spowolnienie pracy podsystemu pamięci masowej.

Cecha 6Podstawowa metodą tworzenia nowych procesów jest ich rozwidlanie, które tworzy kopię aktywnego procesu, która rozpoczyna współbieżną pracę wraz z procesem macierzystym. Fork – funkcja rozwidlająca się tak nazwa, wygląda to tak, że unix mogłoby teoretycznie pracować na jednym pliku wykonywalnym nad jądrem, wtedy startowy plik mógłby się rozwidlać, każdy z nich by wykonywał to co nam się zażyczy, ale nie ma sensu budować programu, który może robić wszystko, dlatego nie zostaliśmy tylko na rozwidlaniu.

Cecha 7Uruchamianie programu przez zastąpienie aktywnego procesu kodem pochodzącym z pliku wykonywalnego. Funkcja zastępująca nazywa się exec, choć tak naprawdę to rodzina funkcji (exeve jest najbardziej pierwotną z nich). Za pomocą pary wymienionych funkcji jest tworzone drzewo uruchamianych procesów. Jądro ma zwykle skonfigurowany program wykonywalny który jest zaczynem tego procesu tworzenia drzewa i nazywa się on zwykle Init – oznacza to ze jądro startuje, przygotowuje zasoby sprzętowe naszego systemu a potem oddaje sterowanie do programu Init, który zrobi to , co jest alej skonfigurowane

Cecha 8Procesy korzystają podczas pracy z łączenia dynamicznego. Fundamentalną biblioteką łączoną dynamicznie jest libc standardowa biblioteka łączenia dynamicznego. Bez niej nie ruszymy, choć nie jest to element absolutnie obowiązkowy, bo da się sobie wyobrazić sytuację, gdzie to obejdziemy.

Page 42: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 42

Cecha 9Komunikacja międzyprocesowa odbywa się przez jądro systemu. (każdy proces pracuje w wyizolowanej przestrzeni adresowej przecież).

Cecha 10Jeżeli jakaś funkcja systemu operacyjnego zajmuje się transferem danych do pamięci operacyjnej to system operacyjny stara się przybliżyć ta funkcjonalność za pomocą zwykłego reada. Read to funkcja która czyta dane z deskryptora plikowego. Read w systemie unixowym ma bardzo rozległe zastosowanie. W Unixie wszystko jest plikiem. Co zrobi polecenie cp /dev/fd0 plik ? cp to program użytkowy, który dla pierwszego argumentu robi open w trybie read only, a dla drugiego open write only a potem pętle w której readuje z pierwszego deskryptora i wsadza do drugiego potem kończy działanie. Fd0 to plik specjalny który modeluje stacje dyskietek. To polecenie zapisuje obraz całej dyskietki do pliku, nie system pliku, który jest zapisany na niej, nie próbuje jej zamontować potem przeczytać pierwszy lik, tylko on traktuje tą dyskietkę jako plik specjalny. Cp plik /dev/fd0 i to z tym wcześniejszym to program do kopiowania dyskietek. Chodzi o to by funkcjonalność była prosta, by dała się składać.

BY dawać wędki a nie rybę ;)

Cecha 11Otwarty plik jest dostępny w procesie przez liczbę całkowitą zwaną deskryptorem. Deskryptory o numerach 0,1,2 sa przypisane do standardowego wejścia wyjście i wyjścia diagnostycznego.

System nie jest wielodostępny sam z siebie, to oprogramowanie na to pozwala. LInux przed uruchomieniem serwera SSH nie jest wielodostępny, potem już jest.

Dalsze cechyW środowisku tekstowych naturalnym środowiskiem pracy jest interpreter poleceń czyli powłoka, a standardowa powłoka Unix jest znormalizowana przez dokument POSIX. Linux wykorzystuje do pracy w środowisku sieciowym rodzinę protokołów TCP/IP, to się rozwijało równolegle z Unixem, dokładniej z BSD i wszystkie mechanizmy które SA w tych protokołach dostępne SA dobrze wkomponowane w budowę wewnętrzną systemu unix, np. gniazdko transportowe jest tez dostępne a pomocą uniwersalnego interfejsu plikowego, czyli deskryptora nie musimy otwierać prze open tylko perze connect która nas połączy z tym c trzeba.

Naturalnym sposobem organizacji pamięci masowej jest model indeksowy oparty na i węzłach. Odwzorowaniem i węzłów na nazwy plików zajmują się pliki specjalne zwane katalogami. I węzeł zawiera wszystkie informacje o pliku poza jego nazwą i gromadzi je w strukturze danych o stałej długości, ale z tego i niewielkiej wielkości i węzła polega wada – nie SA one wyposażone w dynamiczne listy kontroli dostępu. Chodzi o to ze nie możemy stwierdzić, ze osoba x ma taki dostęp do pliku, a osoba y inny. Tu i węzeł jest statyczny.

Cecha:Unikowy system plików jest widoczny jako wielopoziomowe drzewo, czyli system nie numeruje urządzeń pamięci masowej, są one podłączane do jednolitego drzewa katalogowego. Przekłada się to na to, że pełna ścieżka nie zawiera indeksu, nie ma czegoś takiego jak c:, wszystko jest od jednego korzystania. Obsługiwanych może być wiele urządzeń ale każde z nich musi być odwzorowane w strukturze katalogowej.

Plik danych jest ciągiem bajtów.

Page 43: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 43

W linuxie (unix?) obowiązuje model administracyjny bazujący na ograniczonym zaufaniu do użytkownika. Większość funkcji systemu operacyjnego rozpatruje na wejściu numeryczny identyfikator wywołującego je użytkownika, jeśli jest on równy 0 to użytkownik ma pełen dostęp do funkcji systemu operacyjnego. Jeżeli ten numer identyfikacyjny jest różny od zera to to czy dostęp będzie dozwolony czy nie zależy od innych czynników np. cech pliku. Użytkownik o numerze 0 może zmienić swoją tożsamość na użytkownika o numerze niezerowym, w drugą stronę ie idzie, wyjątkiem jest uruchamianie specjalnego rodzaju plików wykonywalnych oznaczonych atrybutami SUID lub SGID. W normalnym modelu administracyjnym im dalej w procesach potomnych tym większe prawdopodobieństwo ze natrafimy na procesy należące do użytkowników administracyjnych.

„Przedzierzgnięcie na zalogowanego użytkownika „ ;)

Program pracuje w pewnym otoczeniu tekstowym składającym się z nazw i stowarzyszonych ze sobą wartości. (zobaczymy to środowisko jak wpiszemy set).

Standardowa budowa drzewa plikowego systemu unix

Standardowa budowa drzewa plikowego systemu unix

Rozmawiamy o jądrze Unixa, jakie jądro ma być wystartowane, w jakim trybie itp. Czyli mamy wyrafinowane programy startowe bootujące, niektórzy marzą by wyświetlono im jakąś bitmapę podczas startu itp. Zatem procedura bootowania nie będzie procedurą jednostopniową, ta procedura zapisana w biosie naszych systemów ma aktywować pierwszą fazę tego bootowania a potem ona wywoła drugą fazę i dopiero potem mamy prawdziwe załadowanie systemu. Zatem jądro z pewnymi parametrami jest aktywowane, te parametry są inicjalizowane, mamy komunikaty o skonfigurowanych w jądrze urządzeniach wejścia i wyjścia a potem jak już się wszystko załaduje, to jądro ma coś robić gdy już się zainicjalizuje, to całość jest w gestii oprogramowania użytkowego. Więc jeśli byśmy spróbowali zrobić sami system operacyjny, nie z dystrybucji, tylko byśmy sami w odpowiednim miejscu zainstalowali jądro, zrobili dla niego procedurę bootowania i zobaczyli co dzieje się dalej. Cały proces bootowania ma wyjść na powierzchnię do userspace. Jądro będzie miało na pewno program który po starcie jądra się uruchomi i ten program musimy skądś wziąć, czyli jądro musi mieć możliwość bezpośrednio po starcie (prze wykonaniem kroków operacyjnych) obsługi przynajmniej jednego systemu plików, na którym będzie zapisany plik startowy, który potem może sterować startem naszego systemu, czyl mamy takie pewnego rodzaju zamknięte koło. Sterowniki urządzeń mogą być jeszcze nie załadowane itp. Ale nadal jądro musi mieć dostęp do plików by pokierowały jego dalszymi ruchami.

Start systemu BSD

Zatem w nasze monolityczne jądro możemy wmontować obsługę wszystkich możliwych dysków. Jądro bezpośrednio po starcie zrobi montaż do korzenia drzewa katalogowego system plików zapisany na pewnej partycji danego urządzenia. W przypadkach nieskomplikowanych to się sprawdza. Alternatywa: jądro może mieć zdefiniowaną wstępnie obsługę urządzenia wirtualnego, no RAMdysku, system pliku zorganizowany w pamięci operacyjnej na poziomie oprogramowani użytkowego jest widziany tak samo jak dysk czy pendrive, ale pewna faza bootowania może wypełni ten RAMdysk tym, co potrzeba typu krypty konfiguracyjne które ustalą właściwy porządek i jądro jak wystartuje to przełączy obie ten wirtualny system plików i będzie korzystał z modułu jądra konfiguracyjnego które tam będą napisane. Rozpocznie się więc wtedy druga faza, ona m.in. przełączy korzeń na korzeń dyskowy. Faza startu kończy się na programie init, proces startu jest wspólny dla obu rodzin(z ostatniego wykładu) z dokładnością do nazwy pliku, ale różni się tym co dalej robią. Jądro ma fazę ścieżkową zapisaną wewnątrz /sbin/init i możliwą do zmiany, jądro stara się ten plik uruchomić.

Page 44: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 44

Te systemy z rodziny BSD są bardziej prymitywne pod kątem tego co ma w sobie init. To co robią te systemu może przypominać start przedpotopowego systemu jakim jest Dos czyli po wystartowaniu jądra startuje program init który za pomocą interpretera poleceńuruchamia jakiś zestaw startowy, w Dosie się to nazywało autoexec bat. Coś potem było o /etc/rc, on ładuje jakieś defaultsy najpierw, a potem ewentualne korekty wykonane na naszych plikach konfiguracyjnych, są tam rozpatrywane różne warunki iw zależności od ich wyniku pewne programy będą startowane lub nie. Chodzi o to ze być może system będzie startował w trybie naprawczym itp. Zatem to co się bedzie działo w pliku rc jest określone na poziomie konkretnych dystrybucji. Teoretycznie mżymy rc wywalić i wprowadzić naszą logikę procesów przy startowych. Możemy też wywalić sbin/init i zastąpić naszym programem. Klasycznym przykładem podstawki za init to mechanizm uruchamiany w konsolach ratunkowych, tam zamiast interptera poleceń startują inne rzeczy np. busybox, to jest wielki gabarytowo program wykonywalny, który w zależności od sposobu wywołania jest cp, mountem itp. + stosowne biblioteki dynamiczne które są statycznie wmontowane w ten program, by mógł być on całkowicie samodzielny i taki wielki kocioł exec jest też interpreterem poleceń po to by mieć możliwości zarządzania systemem bez konieczności budowy tego wielkiego drzewa. Wszystko w jednym a nie osobne pliki, bo tak jest łatwiej i zajmuje mniej miejsca.

Start systemu V

Najpierw powiedzmy sobie o pewnym przełączniku, w który wyposażone były komputerowy produkowane przez Digital na których NTNT implementowały swój system. Ten przełącznik był 6pozycyjny i pozwalał na włączanie systemu. Narysował prowadzący kółko i na godzinie 12 było 0, a na 6 było 5, gdzieś obok był reset i komputer się wlączało tak ze najpierw ze stanu 0 się przechodziło w stan 1 (czyli mamy single user czyli podstawowy tryb) a potem przełączało się go na multiuser. Potem więc pomyślano, by start systemu był zdefiniowany pewnymi poziomami pracy i mniejsza o to co one miały robić, ważne było tylko że level 0 to halt, 1 to single, 2-5 to multi a 6 to reboot i użytkownik może zdefiniować sobie jak będzie jego system startował byle to miało logikę czyli 0->1->któryś z trybów multi,. Jak naciskamy 6 to znaczy ze przechodzimy do single i stamtąd zamykamy system. Pytanie co to znacy przejść między trybami? W trybie single musimy sobie zapewnić ze nasz komp nie świadczy usług zewnętrznych, nie jest zdolny do podejmowania pracy wielozadaniowej, chodzi o to by jak my będziemy robić kroki naprawcze to by jakiś inny administrator nie prowadził równolegle swoich kroków naprawczych. Zatem przejście z trybu single do multi NIE oznacza ze system będzie w trybie wieloprogramowym czy wielozadaniowym, tylko ze pewne programy musza być startowane i już, np. na pewno jest startowany system dostępu ssh.

/etc/init.d tu mamy skrypty związane ze startem naszego systemu., skrypty te muszą mieć możliwość wywołania z dwoma argumentami stop i start. Pamiętajmy, że start podsystemu może się wiązać z dodatkowymi czynnościami. To jest zaleta o tyle, ze jeśli w naszym systemie dodano jakies podsystemu, to ta paczka może wrzucić zarówno części wykonywalne i skrypty do odpowiedniego katalogu i nie musimy się już niczego domyślać. To takie fajne elastyczne rozwiązanie. Skrypty startujących podsystemów –mamy plik globalny /etc/inittab to plik tekstowy o ustalonej składni jednej linii:Et: lista trybów pracy: sposób uruchomienia: skrypt

Et to etykieta unikalna z pewnych względów jeśli Nb chcemy przeładować jakiś tryb pracy.W tym inittab może być np. taki wpis:L1:1:wait:/etc/rc 1

Ta linia okresla, że jeśli komp przechodzi do trybu 1 to ma być uruchamiany /etc/rc z argumentem 1.

Page 45: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 45

Co robią skrypty rc?To nie jest autoexec, tylko te pliki, skrypty usiłują przeanalizować to, o jest zawarte w podkatalogu /etc/rcX.d, gdzie X oznacza numer. W tych katalogach są pliki o dziwnych nazwach, jeśli np. w init.d był plik Apacze (służy do obsługi serwera WWW) to w rcX znajdziemy S90apache czyli łącznik symboliczny do pliku Apache. S oznaca by wystartować a 90 oznacza kolejność wykonywania kolejnych operacji, a łącznik symboliczny oznacza ze nie ma sensu dublowac tego skryptu tylko go podlinkować.

rcX rozpoczyna wykonywanie łączników symbolicznych zawartych w odpowiednich katalogach. Jeśli te łączniki zaczynają się na literkę K to uruchamiane są skrypty z argumentem stop, a jeśli s to z argumentem start, czyli każdy tryb ma dokładnie zdefiniowaną kolejności i listę podsystemów które mają być najpierw zamknięte a potem podsystemów które mają być potem otwarte.

Single user jest zbudowany tak ze wszystkie podsystemy SA najpierw zamykane a potem jest jeden z uruchomieniem pojedynczego interpretera poleceń do zarządzania systemem.

By wyłączyć start danego podsystemu to kasujemy łącznik syboliczny,. Co zrobić by mieć tryb pracy z apache i bez Apache to znaczy ze mamy przekopiować łączniki symboliczne z rc2.d to rc3.d , a tam chyba skasować i mamy wtedy te dwa tryby.

Jakie programy są zestandaryzowane w systemach unikowych?Oprogramowanie do zarządzania plikami i katalogami czyli wszystkie cp, mkdir itp., bez względu na system unikowy w jaki to wpiszemy to się ucieszymy. Problem jest cshell , jakiś bornshell i coś tam jeszcze dziwnego..

To co jeszcze łączy nasz system unikowy to normatywny wygląd drzewa plikowo katalogowego, byśmy wiedzieli czego gdzie szukać w tym drzewie .

Page 46: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 46

Te w sbin są dynamicznie ładowane ? więc wskazujemy gdzie są do nich biblioteki po to jest lib

Te w sbin maja charakter rozruchowy, a te które SA potrzebne późnie SA w bin, ale w bin nie ma wszystkich programów wykonywalnych dostępnych dla danego systemu, tam SA programy potrzebne di wykonywania najbardziej fundamentalnych zadań m.in. zadania związane z naprawą systemu, konfiguracją startu systemu, związane z trybem awaryjnym, występuje tuSh interpreter borne’aLs

Obecnie w dev nie mamy wymienionych wszystkich dysków ani partycji jak to było dawniej, tylko w momencie inicjalizacji danego urządzenia sprzętowego to odpowiednia rzecz jest tu dokładana

Sbin Init Ifconfig shutdown

Etc Inittab passwd

Lib Libc.so

Dev Ad0 Ad0s1

Bin sh

tmp

Page 47: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 47

Nomenklatura w dev nie jest zestandaryzowana, co bardzo utrudnia nam życie. Np. teraz zwykle w dev nie ma już kart sieciowych, które kiedyś były itp.

Tmp tam są oczywiście pliki tymczasowe.

W USR jest całe oprogramowanie, to co się tam znajduje jest powtórzeniem tego , co znajduje się w katalogu głównym, bo też tam jest bin, sbin, lib itp. W bin będzie kompilator cc, w sbin będzie inetd (plik wykonywalny takiej usługi startowanej przy starcie systemu), w lib będzie jakaś biblioteka np. developerska. Pełen rysunek ręcznie od Krzysia ;). Czyli w lib jest np. libc.a. to czego nie było na poziomie katalogu głównego to np. include czyli tam są nagłówki w języku c do kompilatora języka c i innych fajnych narzędzi developerskich, język c jest na wyposażeniu wszystkich systemów unixowych. W niektórych systemach jest rozdział między aplikacjami dołączanymi razem z dystrybucją i tymi poza dystrybucją, jeśli ten rozdział jest to w usr jest podkatalog local a tam powtórka: bin, sbin, lib, include, ale kolejnego local już nie będzie ;)

Jeśli instalujemy sobie jakąś dziwną dystrybucję systemu (brzmiąca jak debian cokolwiek naprawdę powiedział) i chcemy dodać coś od siebie to niezłym pomysłem jest byśmy niemieszali z tym co już jest więc to co my tam wsadzimy wsadzamy do local. Czyli jeśli przekompilujemy jakiś program z systemu portów to on sam się wpakuje do local. Jeśli zaś napiszemy coś co ma być dostępne dla wielu użytkowników to możemy pomyśleć o lokalu w lokalu. Dalej na prawo byłoby home, w starszych systemach nazywał się u. w home może być głębsza struktura dzieląca użytkowników na klasy albo już katalogi domowe naszych użytkowników. Ostatnim czego nam brakuje to katalog var, tam są gromadzone informacje systemowe (lub te potrzebne do poprawnego działania podsystemów czy aplikacji, ale o charakterze często zmiennym). Najbardziej klasycznym przedstawicielem grupy takich plików są logi systemowe, czyli dzienniki pracy zarówno systemu jak i różnych podsystemów uruchomionych w tym systemie. W katalogu var jest też spool, tam są kolejki różnych podsystemów jeśli mamy jakieś podsystemu kolejkujące czyli np. podsystem drukowania czy poczty elektronicznej, to ich podsystemy kolejkowania są w spool. W var często jest robiony jeszcze jeden tmp, wtedy aplikacja zamiast do tmp zapisze coś w var/tmp by zoptymalizować całość.

Zwyczajowo całość nie jest zawarta Na jednym urządzeniu, a to czy tak będzie czy nie zależy od zastosowania naszego systemu. Jeśli używamy systemu unixowego jako systemu desktopowego to to co się dzieje z prawej strony nie będzie takie bardzo zmienne, wtedy wydzielanie osobnego var może się mijać z celem. Ale jeśli mamy do czynienia z serwerem to sytuacja może być taka, ze usr jest katalogiem który nie podlega za dużym zmianom, tam zbiór oprogramowania jest przez wieki taki sam, co najwyżej aktualizowany. Dlatego w stacji roboczej całość wsadzamy w jedno miejsce, ewentualnie tylko home wsadzamy do innego kompa, a w systemach serwerowych dokonujemy jednak podziału: wyodrębniamy usr, warto bo usr się zmienia tylko w momencie updateu systemu, poza tym czasem te informacje się nie zmieniają. Na osobnym systemie plikowym można też zainstalować fragment local, bo to część o charakterze częściej zmiennym. Warto też przemyśleć wydzielenie home oraz tmp i to tmp jest często przy wydzielaniu łączone z katalogiem var.

Windows NT to mówimy o całej rodzinie systemów przyjmującej różne nazwy marketingowej ,ale to jest jedne trzon oparty na tych samych założeniach a zmienia sir tylko skóra zewnętrzna. Wielozadaniowość z wywłaszczaniem jest cecha całego NT, sprawia się ona lepiej niż klasyczna wieloprogramowość. Początkowo Windows NT był pisany w ten sposób by zachować wsteczną kompatybilność z różnymi wcześniejszymi aplikacjami i platformami systemowymi itp., były podsystemy tłumaczące do tych systemów, one działały raz dobrze, a raz źle.

Dawniej każdy program dosowy był uruchamiany w swojej własnej maszynie wirtualnej, wtedy jak się jeden zawiesił, to reszta jeszcze chodziła, wiec można było uruchamiać

Page 48: jarocki@math.uni.lodz - Kolos Wikikolos.math.uni.lodz.pl/~archive/Systemy operacyjne/Calosc - systemy... · Silberschatz „Podstawy systemów operacyjnych”. W pewnych momentach

Systemy operacyjne 48

dosowe aplikacje w środowisku symulującym wiele komputerów. Gorzej było w 16bitowym Windows, bo tu już była tylko jedna maszyna wirtualna i był kłopot ze wspólną pamięcią okołosystemową… tam jak się jedna aplikacja zawiesiła, to już się wszystko zawieszało. Został wiec tylko Win32 służy do uruchamiania aplikacji windowsów które utylizują wszystkie możliwości tego systemu, maja pełny dostęp do pamięci operacyjnej i umieją się porozumiewać bez żadnych filtrów.

Załzenie było od początku ze system ma być podkręcany przez developerów do różnych zastosowań. Jądro poszczególnych systemów zmienia się tylko jeśli chodzi o ustawienie różnych parametrów niedostępnych dla ostatecznego użytkownika. Te regulacje nie zmieniają istoty działania systemu. System Windows NT był od początku zbudowany w oparciu o architekturę mikrojądra, czyli funkcjonalności jądra mogą być dodawane na gorąco w postaci procesów których kod jest wykonywany w przestrzeni jakiejś… czyli system Windows NT może rozszerzać swoja funkcjonalność o nowe komponenty bez konieczności rekompilacji całego systemu, co jest ważne gdy system ma sterować urządzeniami nieznanymi w momencie produkowania systemu lub uradzaniem o charakterze unikalnym, do których sterowniki nie są publicznie dostępne.

HAL (Hardware Abstraction Line) to biblioteka która zajmuje się podsystemem przerwań, zachowaniem zegara i podsystemem pamięci (podstawowe dla wielozadaniowości podsystemów sprzętowych) zatem teoretycznie nasz system mógł być bez zmian rekompilowany na dowolnej architekturze a zmieniany mógł być tylko Hal czyli warstwa tłumacząca na język ogólny.

Zatem założenie było by Windows NT był łatwo portowalny(?), ale to nie wyszło, jest dedykowany na platformy Intela.

Jeśli chodzi o niezawodność polegająca na sprzętowe ochronie pamięci podobnie jak praca aplikacji w trybie nieuprzywilejowanym.

System jest rozszerzalny w warstwie uprzywilejowanej jednym ze sposobów jest podsystem graficzny.

Wielodostęp tego systemu to rzecz która była bagatelizowana dopiero w XP zdefiniowany cos co pozwala na dostęp do zdalnego pulpitu, wcześniejsze rozwiązania tego typu nie były zintegrowane z systemem.