Systemy Operacyjne
ogólnie
Spis treści
1. Co to jest system operacyjny i jakie są jego podstawowe zadania ?
1. Co to jest system operacyjny i jakie są jego podstawowe zadania ?
Najogólniej system operacyjny można określić jako pośrednika między użytkownikiem a sprzętem komputerowym. S.O. jest ważną częścią prawie każdego systemu komputerowego, który składa się z elementów:
- sprzęt (procesor, pamięć, urządzenia we-wy) stanowi podstawowe zasoby systemu komputerowego
- programy użytkowe (kompilatory, bazy danych - oprogramowanie + dane ) określają sposoby użycia powyższych zasobów
- użytkownicy
Podstawowym celem S.O. jest spowodowanie aby system komputerowy był wygodny w użyciu, drugim celem jest wydajna eksploatacja sprzętu komputerowego. S.O. nadzoruje i koordynuje posługiwanie się sprzętem przez różne programy użytkowe ( pracujące na zlecenie różnych użytkowników ), dostarcza środków do prawidłowego użycia zasobów (sprzęt, oprogramowanie, dane) w działającym systemie komputerowym przydzielając je poszczególnym programom i użytkownikom, gdy są one niezbędne do wykonania ich zadań. Może się zdarzyć (dość często) że zaistnieje konflikt zamówień na zasoby, a więc S.O. musi zdecydować o przydziale zasobów poszczególnym zamawiającym, tak aby działanie całego systemu komputerowego było wydajne.
Jeżeli chcemy zdefiniować S.O. od strony sterowania różnymi urządzeniami we-wy i programami użytkownika to S.O. będzie programem sterującym, który nadzoruje działanie programu użytkownika, przeciwdziała błędom i zapobiega niewłaściwemu użyciu komputera, zajmuje się zwłaszcza kontrolą i obsługą pracy urządzeń we-wy.
Nie ma jednoznacznej definicji określającej S.O. a najogólniejszą będzie taka iż jest to program który działa w komputerze nieustannie (nazywany jądrem), a wszystkie inne programy są programami użytkownika.
Podobnie sprawa wygląda przy określaniu zadań S.O. jednakże najważniejszym celem jest wygoda użytkownika, drugim zaś jest efektywne działanie systemu komputerowego - jest on szczególnie ważny w rozbudowanych, wielodostępnych systemach z podziałem czasu, systemy takie są zazwyczaj bardzo kosztowne toteż zwraca się baczniejszą uwagę na wydajność. Jak widać te dwa cele bywają niekiedy ze sobą sprzeczne.
2. Wyjaśnij pojęcia buforowanie i spooling.
Buforowanie jest to metoda jednoczesnego obliczeń i operacji we-wy dla danego zadania. W momencie kiedy procesor przeczyta dane może zacząć je przetwarzać, wtedy zleca się urządzeniu wejściowemu natychmiastowe rozpoczęcie czytania następnych danych. Dzięki temu jednostka centralna jak i urządzenie wejściowe są zajęte. Tak samo można postąpić na wyjściu czyli procesor będzie posyłał wytworzone dane do bufora, skąd pobiera je urządzenie wyjściowe. Buforowanie pozwala zmniejszać wahania czasu zużywanego na przetworzenie rekordu (porcji danych). Jeżeli średnie prędkości procesora i urządzeń we-wy są takie same procesor przetwarza wszystko z pełną prędkością (może wyprzedzać lub zostawać nieco w tyle za urządzeniem)
Jeżeli natomiast jednostka centralna jest szybsza (a zazwyczaj tak bywa) to dochodzi do sytuacji że procesor opróżni bufor i będzie musiał czekać na dane z urządzenia wejściowego, lub na wyjściu procesor zapełni wszystkie bufory systemowe i będzie musiał czekać aż urządzenie wyjściowe je opróżni. Sytuacja taka ma miejsce jeżeli zadania uzależnione są od we-wy, natomiast w zadaniach uzależnionych od jednostki centralnej obliczeń jest tak wiele że bufory wejściowe są zawsze pełne a wyjściowe - zawsze puste, procesor nie może nadążyć za urządzeniami we-wy. Reasumując buforowanie danych jest w pewnej mierze pomocne jednak nie zadowalające.
Spooling polega na tym,że używa się dysku jako bardzo wielkiego buforu do czytania danych z maksymalnym wyprzedzeniem z urządzeń wejściowych oraz do przechowywania plików wyjściowych do czasu, aż urządzenia wyjściowe będą gotowe do ich przyjęcia. Spooling stosuje się także przy przetwarzaniu danych w instalacjach zdalnych. Na przykład jednostka centralna wysyła przez łącza komunikacyjne do zdalnej drukarki. W tym wypadku przetwarzanie zdalne odbywa się z własną prędkością bez interwencji jednostki centralnej. Procesor powinien być tylko powiadomiony o zakończeniu zadania aby mógł przesłać nowe. W przypadku buforowania wykonywane są operacje we-wy i obliczania dla tego samego zadania, spooling umożliwia równoczesne wykonywanie operacji we-wy jednego zadania i obliczeń dla innych zadań. Buforowanie umożliwia nakładanie operacji we-wy danego zadania tylko na jego `własne' obliczenia, spooling pozwala nakładać operacje we-wy na obliczenia wielu zadań. Dzięki spoolingowi stało się możliwe zwiększenie wykorzystania procesora i urządzeń we-wy, tworzy ważną strukturę danych - pulę zadań. Spooling powoduje, że pewna liczba zadań jest zawczasu przeczytana na dysk, gdzie oczekuje na wykonanie.
3. Przerwanie sprzętowe.
Gdy jakieś urządzenie zgłasza fakt zaistnienia sytuacji krytycznej (np.: klawiatura, gdy naciśnięto klawisze [Ctrl+Break] lub pamięć, gdy występuje błąd parzystości ). W takim przypadku przerywane jest wykonywanie aktualnego programu i pobrana zawartość ustalonego miejsca w pamięci (adres startowy procedury obsługującej przerwanie). Procedura obsługi przerwania przesyła dane z lokalnego buforu do pamięci głównej. Po zakończeniu transmisji CPU jest gotowy do wznowienia przerwanych obliczeń. W ten sposób JC i urządzenia w/w mogą działać współbieżnie. Gdy pojawia się przerwanie rezerwowany jest ciąg komórek na początku pamięci głównej, aby przechowywać tam adresy procedur obsługi przerwań. Tablica ta, zwana wektorem przerwań jest indeksowana numerem urządzenia, które korzysta z przerwania. Adres przerwanego rozkazu jest przechowywany na stosie systemowym. Po obsłużeniu przerwania następuje pobranie zapamiętanego adresu powrotnego i wznowienie przerwanych obliczeń. Podczas obsługi jednego przerwania inne są wyłączane, a po zakończeniu zadania ponownie są włączane. W nowszych systemach możliwa jest obsługa nowego przerwania przed zakończeniem obsługi innego na zasadzie priorytetowej. Poszczególnym żądaniom nadaje się względne priorytety, a adresy poszczególnych przerwań są pamiętane w osobnym miejscu, dla każdego priorytetu. Przerwanie o wyższym priorytecie będzie wykonane nawet wtedy, gdy aktywne jest jakieś inne przerwanie. Jest ono maskowane (czasowo wyłączone) po to, aby go nie stracić.
Dualny tryb pracy komputera dostarcza środków do ochrony systemu przed nieodpowiedzialnym użytkowanie z niego. Ochrona ta jest wspomagana przez oznaczenie niebezpiecznych rozkazów kodu maszynowego jako rozkazów uprzywilejowanych. Sprzęt pozwala na ich wykonanie tylko w trybie monitora (ochrona systemu oraz programów polega na zaopatrzeniu sprzętu w środki pozwalające na rozpoznanie trybów jego pracy, wyróżnia się minimalnie 2 tryby: użytkownika i monitora). Próba wykonania rozkazu uprzywilejowanego w innym trybie potraktowana zostanie jako błąd i uruchomiona zostanie pułapka (jest to rodzaj przerwanie spowodowanego przez błąd np.: dzielenie przez zero, albo przez specjalne zamówienia pochodzące z programu użytkownika).
Przerwania programowe- są one wywoływane tylko z wnętrza programu. Przerwania te stanowią grono użytecznych procedur i funkcji. Właściwie całe programowanie w assemblerze to umiejętne korzystanie z gotowych podprogramów zawartych w przerwaniach. I tak np. w BASICu wypisanie na ekranie monitora ciągu znaków realizuje funkcja „print” to w assemblerze do tej czynności wywoływane jest przerwanie 21H z wartością 9H w AH, Inny sposób wyświetlenia łańcucha jest praktycznie niedostępne.
4. Wieloprogramowość
Zwiększa wykorzystanie procesora i ustawia go w takiej sytuacji, aby zawsze miał coś do roboty. System operacyjny wybiera i rozpoczyna działanie jednego zadania z puli. Jeżeli zadanie oczekuje na operację np.: wejścia/wyjścia, to system przechodzi do innego zadania itd. Kiedy pierwsze zadanie zakończy oczekiwanie, to otrzyma z powrotem dostęp do procesora. Dopóki są jakieś zadania do wykonania, dopóty procesor nie ma przestojów. Aby mieć kilka zadań gotowych do pracy, system musi je wszystkie przechowywać jednocześnie w pamięci.
Wymaga to odpowiedniego zarządzania pamięcią. Ponadto jeżeli w tym samym czasie jest kilka zadań gotowych do wykonania, to system musi wybrać jedno spośród nich. Podejmowanie takich decyzji nosi miano - planowaniem przydziału procesora. Wreszcie, wykonywanie wielu zadań współbieżnie wymaga, by ich potencjalne, wzajemne niekorzystne oddziaływania znajdowały się pod stałą kontrolą systemu, włączając planowanie procesów, magazynowanie danych i zarządzanie pamięcią.
Wielozadaniowość (podział czasu)
Interakcyjny system komputerowy umożliwia bezpośredni dialog użytkownika z systemem (na wyjściu jest klawiatura, na wyjściu monitor lub drukarka). Użytkownik wydaje polecenia, czeka na odpowiedź i o kolejnym poleceniu decyduje na podstawie wyników poprzedniego polecenia. Zadania interakcyjne składają się z wielu krótkich działań, w których rezultaty kolejnych poleceń mogą nie być przewidywalne. Dlatego czas odpowiedzi powinien być możliwie krótki.
W systemie z podziałem czasu zastosowano planowanie przydziału procesora i wieloprogramowości. Tak aby każdy użytkownik mógł korzystać z małej porcji współdzielonego czasu pracy komputera. Każdy użytkownik ma oddzielny program w pamięci. Jeżeli jeden z użytkowników np.: wprowadza dane z klawiatury (w tym czasie procesor byłby bezczynny), to CPU może wykonywać program innego użytkownika. Zazwyczaj każdemu użytkownikowi wystarcza mały przydział czasu CPU, a dzięki szybkim przełączeniom systemu między użytkownikami, każdy z nich odnosi wrażenie, że dysponuje własnym komputerem (teoretycznie).
Podobnie jak w wieloprogramowości, poszczególne zadania muszą być jednocześnie przechowywane w pamięci, co wymaga, jej ochrony i planowania przydziały CPU.
Idea ww. systemów została zaprezentowana już w roku 1960, wprowadzono ją w życie dopiero w latach `80.
5. Co to są systemy rozproszone?
Występują w słabo powiązanych systemach, gdzie każdy procesor ma własną pamięć lokalną, a procesory komunikują się za pomocą linii komunikacyjnych (szyn szybkiego przesyłania danych).
Procesory określa się za pomocą kilku nazw: stanowiska, węzły, komputery, maszyny. Przeważnie jedno stanowisko (serwer) zarządza zasobami, z których korzystają inne stanowiska - klienci (użytkownik). Zadaniem systemu rozproszonego jest tworzenie wydajnego i wygodnego środowiska do tego rodzaju dzielenia zasobów.
Cztery gł. Powody uzasadniają budowę systemów rozproszonych:
a) Dzielenie zasobów - stanowi mechanizm umożliwiający dzielenie plików na zdalnych stanowiskach, przetwarzanie informacji w rozproszonych bazach danych, drukowanie plików na zdalnych stanowiskach (np.: użytkownik A korzysta z drukarki ze stanowiska B itp.), wykorzystywanie specjalnych urządzeń sprzętowych (np.: procesor macierzowy).
b) Przyspieszenie obliczeń - konkretne obliczenie jest rozdzielane na pewną liczbę obliczeń częściowych.
Z kolei s.r. rozdziela obliczenia między różne stanowiska tak aby mogły być wykonywane jednocześnie.
Jeżeli jakieś stanowisko jest przeładowane, to system przesuwa zadanie na inne stanowisko (ładowanie dzielone).
c) Niezawodność - w przypadku awarii jednego stanowiska system nie przerywa pracy, ale przenosi zadanie na inne stanowisko. Gdy uszkodzone stanowisko zostanie naprawione, to następuje gładkie włączenie stanowiska z powrotem do systemu.
d) Komunikacja - jeżeli połączonych jest kilka stanowisk za pomocą sieci komunikacyjnej, wówczas jest możliwość wymiany na niskim poziomie - komunikatów, na wysokim - plików. Zaletą jest komunikacja na duże odległości (możliwość pracy dwóch osób nad jednym projektem na oddalonych od siebie stanowiskach).
Stanowiska mogą być fizycznie połączone na różne sposoby:
- Połączenie pełne - Każde stanowisko połączone jest bezpośrednio z innymi stanowiskami w systemie. Koszty są b. wysokie, ale także jest to system niezawodny (musiało by ulec zniszczeniu wiele stanowisk aby system uległ awarii).
- Połączenie częściowe -
- Hierarchia - Stanowiska tworzą strukturę drzewiastą ( typową dla sieci instytucji i urzędów)
- Gwiazda - Jedno stanowisko systemu połączone jest ze wszystkimi pozostałymi stanowiskami.
- Pierścień - Kształt pierścienia, może być jedno lub dwu kierunkowy.
- Szyna wielodostępna - Wszystkie stanowiska są bezpośrednio połączone do pojedynczego łącza, które może mieć organizację linii prostej.
W systemach rozproszonych użytkownicy uzyskują dostęp do zdalnych zasobów w taki sam sposób, jak do zasobów lokalnych. Przemieszczanie danych i procesów odbywa się pod nadzorem S.O.
Przemieszczanie danych:
1) przesłanie całego pliku ze st. A na st. B.
przesłanie tylko tej porcji pliku, która jest niezbędna do natychmiastowego działania.
6. System operacyjny czasu rzeczywistego.
System czasu rzeczywistego bywa często stosowany jako sterownik urządzenia o ściśle określonym zastosowaniu.
Czujniki dostarczają dane do komputera który analizuje te dane i odpowiednio reguluje działanie kontrolowanego obiektu, tak aby zmieniły się wskazania wejściowe czujników.
Przykłady systemów czasu rzeczywistego, np. system :
- sterowania procesami przemysłowymi,
- nadzorowania ekspertów naukowych,
- obrazowania badań medycznych itp.
Systemy operacyjne czasu rzeczywistego mają ściśle zdefiniowane stałe ograniczenia czasowe. Przetwarzanie danych musi się zakończyć przed upływem określonego czasu bo w przeciwnym razie system nie spełnia wymagań. Duże wymagania czasowe powodują, że wszystkie dane przechowywane są w pamięci o krótki czasie dostępu lub w pamięci ROM. Brak jest większości cech nowoczesnych systemów operacyjnych np. pamięci wirtualnej, które zwiększają niepewność odnośnie do ilości czasu używanego przez operacje.
7. Podstawowe własności systemu operacyjnego.
1. Wieloprogramowość. (patrz pytanie 4)
2. Wielozadaniowość. (patrz pytanie 4)
3. Buforowanie. (patrz pytanie 2)
4. Spooling (patrz pytanie 2)
5. Praca w trybie wsadowym - charakteryzuje się brakiem bezpośredniego nadzoru ze strony użytkownika podczas wykonywania zadania. Zadania są przygotowywane i przedkładane. System operacyjny czyta zazwyczaj cały strumień odrębnych zadań. W późniejszym czasie pojawiają się wyniki.
6. Praca w trybie interakcyjnym (bezpośrednim) - system komputerowy umożliwia bezpośredni dialog użytkownika z systemem. Użytkownik wydaje bezpośrednio instrukcje systemowi operacyjnemu lub programowi i otrzymuje natychmiastowe odpowiedzi.
7. System plików dostępnych bezpośrednio.
8. Opisz jak w systemach operacyjnych wygląda przesyłanie danych sterowane przerwaniami i z wykorzystaniem mechanizmu DMA?
Wieloprogramowość i podział czasu mogą istnieć dzięki równoczesnemu wykonywaniu operacji procesora i urządzeń wejścia-wyjścia. Aby to było możliwe, musi istnieć mechanizm ich desynchronizacji i resynchronizacji. W większości systemów najbardziej popularne są dwie metody:
- przesyłanie danych sterowane przerwaniami;
- przesyłanie danych na zasadzie bezpośredniego dostępu do pamięci (DMA - direct memory acces) a. Przesyłanie danych sterowane przerwaniami.
Każdy sterownik urządzenia zewnętrznego ma pod opieką specyficzny typ urządzenia. Sterownik urządzenia zewnętrznego rozporządza lokalnym buforem i zbiorem rejestrów o specjalnym przeznaczeniu. Odpowiada on również za przesyłanie danych między urządzeniem zewnętrznym, które nadzoruje, a jego własną pamięcią buforową.
Aby zainicjować przesyłanie danych, procesor wprowadza pewne liczby do odpowiednich rejestrów sterownika urządzenia, po czym wznawia normalną pracę. Sterownik urządzenia bada wówczas zawartość tych rejestrów, aby określić, jakie ma podjąć działanie. Kiedy przesyłanie danych zakończy się, wtedy sterownik poinformuje jednostkę centralną, że zakończył swoje działanie. Dokonuje tego za pomocą sygnału przerwania.
Procesor po otrzymaniu sygnału przerwania wstrzymuje swoją bieżącą pracę i natychmiast pobiera zawartość ustalonego miejsca pamięci. Miejsce to na ogół zawiera adres startowy procedury obsługującej dane przerwanie. Procedura obsługi przerwania przesyła dane z lokalnego buforu sterownika urządzenia do pamięci głównej. Po zakończeniu przesyłania danych procesor jest gotowy do wznowienia przerwanych obliczeń.
b. Przesyłanie danych z wykorzystaniem mechanizmu DMA.
Po określeniu buforów, wskaźników i liczników sterownik danego urządzenia przesyła bezpośrednio cały blok danych między własnym buforem a pamięcią bez interwencji procesora. Przerwanie wypada wówczas raz na cały blok danych, a nie po przesłaniu jednego znaku lub słowa.
Program użytkownika lub sam system operacyjny może zażądać przesłania danych. System operacyjny wybiera bufor (pusty wejściowy lub pełny wyjściowy) z kolejki buforów do przesłania (bufory mają zazwyczaj 128-4096 B). Następnie odpowiednie adresy źródła i miejsca przeznaczenia umieszcza się w rejestrach sterownika DMA. Dokonuje tego na ogół program obsługi urządzenia, który wie dokładnie, w jaki sposób informacja ta ma być dostarczona sterownikowi DMA. Po tym zabiegu sterownik DMA dostaje za pośrednictwem bitów sterujących w rejestrze kontrolnym informację, że należy zainicjować operację wejścia-wyjścia. Po jej zakończeniu sterownik DMA wysyła przerwanie do procesora.
9. Jak wygląda sprzętowa ochrona w systemach operacyjnych. Na czym polega dualny tryb pracy procesora?
Program użytkownika może zakłócić normalne działanie systemu wydając niedozwoloną instrukcje we-wy, docierając do komórek pamięci w obrębie samego systemu operacyjnego lub nie zwalniając procesora. Aby ustrzec użytkownika przed wykonywaniem niedozwolonych operacji we-wy przyjęto, że wszystkie rozkazy we-wy są uprzywilejowane. Użytkownicy nie mogą wobec tego używać bezpośrednio tych rozkazów, lecz muszą to robić za pośrednictwem systemu operacyjnego. Jeżeli komputer pracuje w trybie użytkownika, to przechodzi do trybu monitora przy każdym wystąpieniu przerwania lub pułapki, wykonując skok pod adres określony w wektorze przerwań.
System operacyjny powinien też chronić wzajemnie programy użytkowników. Istnieje kilka sposobów sprzętowych. Jeden z nich polega na wykorzystaniu rejestrów, zwanych bazowym i granicznym. Pierwszy z nich przechowuje najmniejszy dopuszczalny adres fizyczny pamięci, drugi zaś zawiera rozmiar obszaru pamięci. Ochronę taką sprawuje sprzęt jednostki centralnej przez porównywanie każdego adresu wygenerowanego w trybie pracy użytkownika z zawartością powyższych rejestrów. Każdy błąd kończy się pułapką monitora i w ten sposób program użytkownika jest strzeżony przed zmodyfikowaniem kodu lub struktur danych systemu operacyjnego lub innych użytkowników.
System operacyjny musi strzec program użytkownika przed wpadnięciem w nieskończoną pętlę, gdyż grozi to odebraniem sterowania systemowi operacyjnemu na zawsze. Osiąga się to przez zastosowanie czasomierza (ang. timer). Można go tak ustawić, by generował w komputerze przerwanie po wyznaczonym okresie czasu - wtedy sterowanie wraca do syst. op.
Czasomierz znajduje również zastosowanie przy podziale czasu. W najprostszym przypadku czasomierz może być nastawiony na przerwanie co stały okres, przy czym okres ten jest chwilą przydzielaną każdemu użytkownikowi na działanie, zanim następny użytkownik nie przejmie nadzoru nad procesem. System operacyjny jest wywoływany po każdej chwili, głównie w celach administratorskich, a także by odświeżyć stan rejestrów, zmiennych wew. i buforów oraz „przygotować pole” następnemu programowi.
Dualny tryb pracy komputera również służy do ochrony sprzętowej. Polega on na tym, że rozróżnia się dwa tryby pracy komputera: użytkownika i monitora (nadzorcy). Sprzęt komputerowy uzupełnia się o tzw. bit trybu, który mówi o tym, czy zadanie zamawiane było przez system czy program użytkownika. Po wystąpieniu pułapki lub przerwania, sprzęt zmienia swój tryb pracy na tryb pracy monitora (bit=0). Dualny tryb pracy komputera opiera się na koncepcji rozkazów uprzywilejowanych, których wykonywanie jest możliwe tylko w trybie monitora. Rozkazy we-wy, rozkazy zmieniające zawartość rejestrów zarządzania pamięcią lub rejestrów czasomierza są uprzywilejowane. Użytkownik, aby skorzystać z takich rozkazów musi „poprosić” monitor, aby ten taką operację wykonał.
10. Struktura systemu operacyjnego na przykładzie MS DOS i Unix.
System tak rozległy i złożony, jak współczesny system operacyjny, musi być konstruowany starannie, jeśli ma działać właściwie i dawać się łatwo modyfikować. Powszechnie stosowanym podejściem jest podzielenie tego na małe części.
Istnieje jednak wiele systemów nie mających dobrze określonej struktury. Systemy te powstały najczęściej jako małe, proste i ograniczone systemy operacyjne, które następnie rozrastały się przekraczając pierwotne założenia. Typowym przykładem jest tu MS DOS. Napisany został pod kątem uzyskania maksymalnej funkcjonalności przy oszczędności miejsca, więc nie starano się o jego wyraźną modularyzację. W systemie tym można wyróżnić pewną strukturę, ale interfejs i poziomy funkcjonalne nie są wyraźnie wydzielone. Na przykład programy użytkowe mogą korzystać z podstawowych procedur we-wy w celu np. bezpośredniego pisania na ekran lub dyski. MS DOS nie jest przez to odporny na skutki błędów w programach użytkowych, co może doprowadzić do zawieszenia się systemu lub np. wykasowania zawartości pamięci dyskowych. MS DOS posiada też ograniczenia sprzętowe - nie ma dualnego trybu pracy, ochrony sprzętowej i innych udogodnień.
W ostateczności można wyróżnić kilka warstw systemu MS DOS. Od najniższego poziomu: programy obsługi urządzeń w pamięci ROM BIOS, programy obsługi urządzeń z poziomu MS DOS, rezydujące programy systemowe i najwyżej - programy użytkowe.
Inny przykład ograniczonej strukturalizacji systemu stanowi oryginalny system operacyjny Unix, który również początkowo był ograniczany przez cechy sprzętu. Unix składa się z dwóch części: jądra i programów systemowych. Jądro dzieli się na ciąg interfejsów i programów obsługi urządzeń, które dodawano i rozszerzano przez lata rozbudowy systemu. W systemie Unix można wyróżnić następujące warstwy:
- sterowniki terminali, urządzeń i pamięci
- programy obsługi terminali, systemy znakowego i blokowego we-wy, system plików, wymiana, programy obsługi dysków i taśm, planowanie przydziału procesora, pamięć wirtualna i stronicowanie - to wszystko stanowi tzw. jądro systemu.
- programy shell i polecenia, kompilatory i interpretatory, biblioteki systemowe
- poziom użytkowników
Za pomocą funkcji systemowych jądro zarządza systemem plików, planuje przydział procesora, zarządza pamięcią i wykonuje wiele innych czynności. Programy systemowe korzystają z zawartych w jądrze funkcji systemowych w celu wykonywania użytecznych działań, jak np.kompilacja programów czy operowanie plikami.
Funkcje systemowe definiują interfejs programisty z systemem.
Nowe wersje systemu Unix zaprojektowano z myślą o lepszym sprzęcie. Jeśli dysponuje się lepszym sprzętem, to można podzielić system operacyjny na mniejsze, lepiej dobrane fragmenty, niż było to możliwe w oryginalnych wersjach systemu. To z kolei sprawia, że system operacyjny ma znacznie większą kontrolę nad komputerem, z czego mogą korzystać programy użytkowe.
11. Jakie funkcjonalne moduły można wyróżnić w systemie operacyjnym. Omów każdy z nich i wymień realizowane przez nie zadania.
System operacyjny tworzy środowisko, w którym są wykonywane programy. Aby skonstruować takie środowisko, system operacyjny dzieli się logicznie na mniejsze moduły i tworzy dobrze określony interfejs z wykonywanymi programami. W różnych systemach można wyodrębnić inne moduły, ale generalnie można wyróżnić następujące:
- moduł zarządzania procesami
- moduł zarządzania pamięcią operacyjną
- moduł zarządzania pamięcią pomocniczą
- moduł zarządzania systemem we-wy
- moduł zarządzania plikami
- moduł systemu ochrony
- moduł pracy sieciowej
- moduł systemu interpretacji poleceń
Zarządzanie procesami.
Proces to program, który jest wykonywany. Może to być program użytkownika, ale także zadanie systemowe, np. spooling. Proces korzysta z pewnych zasobów, takich jak czas jednostki centralnej, pamięć, pliki, urządzenia we-wy. Na tym m.in. polega zarządzanie procesami.
Konkretnie, moduł ten odpowiada za następujące czynności:
- tworzenie i usuwanie procesów
- wstrzymywanie i wznawianie procesów
- dostarczanie mechanizmów synchronizacji procesów
- dostarczanie mechanizmów komunikacji procesów
- dostarczanie mechanizmów obsługi blokad.
Zarządzanie pamięcią operacyjną.
Pamięć operacyjna jest wielką tablicą danych, z której korzysta procesor jak i urządzenia we-wy.
Jeśli chcemy uzyskać zarówno lepsze wykorzystanie jednostki centralnej, jak i szybszą reakcję komputera na polecenia jego użytkowników, to trzeba przechowywać kilka programów w pamięci operacyjnej. Wybór sposobu zarządzania pamięcią zależy od wielu czynników, a zwłaszcza od cech sprzętu, w którym działa dany system. Każdy algorytm wymaga swoistego wspomagania sprzętowego. W odniesieniu do tego modułu system operacyjny odpowiada za następujące czynności:
- utrzymywanie ewidencji aktualnie zajętych części pamięci wraz z informacją, w czyim są władaniu
- decydowanie o tym, które procesy mają być załadowane do zwolnionych obszarów pamięci
- przydzielanie i zwalnianie obszarów pamięci stosownie do potrzeb
Zarządzanie pamięcią pomocniczą.
Podczas wykonywania programy oraz używane przez nie dane muszą znajdować się w pamięci operacyjnej. Pamięć ta jest jednak za mała, aby nieustannie mieścić wszystkie dane i programy. System komputerowy musi mieć zatem dodatkową pamięć pomocniczą, stanowiącą zaplecze dla pamięci operacyjnej.
Moduł odpowiada za następujące czynności:
- zarządzanie obszarami wolnymi
- przydzielanie pamięci
- planowanie przydziałów obszarów pamięci dyskowej
Zarządzanie systemem wejścia-wyjścia.
Jego celem jest ukrywanie przed użytkownikiem szczegółów dotyczących specyfiki urządzeń sprzętowych. Np. Unix ukrywa osobliwości urządzeń we-wy dzięki tzw. systemowi we-wy. System ten składa się z:
- systemu buforowo-notatnikowego
- ogólnego interfejsu do programów
- programów obsługi poszczególnych urządzeń sprzętowych.
Zarządzanie plikami.
Jest to jedna z najbardziej widocznych części systemu operacyjnego. System operacyjny definiuje pliki, czyli jednostki logiczne przechowywanej informacji, niezależnie od fizycznych właściwości używanych urządzeń pamięciowych. System operacyjny musi zatem odwzorowywać pliki na urządzenia fizyczne.
Poza tym, jeśli wielu użytkowników ma dostęp do plików, to może być pożądane sprawowanie pieczy nad tym, kto i w jaki sposób korzysta z tego dostępu. W odniesieniu do tego modułu system operacyjny odpowiada za następujące czynności:
- tworzenie i usuwanie plików
- tworzenie i usuwanie katalogów
- dostarczanie elementarnych operacji do manipulowania plikami i katalogami
- odwzorowywanie plików na obszary pamięci pomocniczej
- składowanie plików na stałych nośnikach pamięci
System ochrony.
czyli przestrzeganie własnej przestrzeni adresowej, nie pozwolenie, aby proces na stałe przejął kontrolę nad jednostką centralną, dualny tryb pracy procesora. Ochrona jest mechanizmem nadzorowania dostępu programów, procesów i użytkowników do zasobów systemu komputerowego. Zwiększa rzetelność poszukując błędów w interfejsach.
Praca sieciowa.
System rozproszony jest zbiorem procesorów, które nie korzystają ze wspólnej pamięci ani zegara.
Procesory komunikują się ze sobą za pomocą linii komunikacyjnych, jak np. szyna danych czy linia telefoniczna. Procesory w systemie rozproszonym są połączone za pomocą sieci komunikacyjnej, która może być różnie skonfigurowana. System taki ma wiele zalet, a system powinien umożliwiać komunikację w tej sieci oraz jej nadzór.
System interpretacji poleceń.
Jest to program, który wykonuje się przy inicjowaniu zadania lub gdy użytkownik rejestruje się w systemie. Wiele żądań jest przekazywanych do systemu operacyjnego za pomocą interpretatora poleceń.
Polecenia rozpoznawane przez interpretator dotyczą: zarządzania procesami, obsługi we-wy, administrowania pamięciami, dostępu do plików, ochrony zasobów i pracy sieciowej.
12. Co to jest proces? Omówić proces sekwencyjny i pojęcie stanu procesu.
Proces to najogólniej wszystkie zadania, jakie wykonuje procesor. Mogą to być zadania systemu wsadowego, programy użytkownika, a także wew. czynności procesora (np. spooling).
Określając nieformalnie, proces sekwencyjny jest wykonywanym programem. Wykonanie procesu musi przebiegać w sposób sekwencyjny. Oznacza to, że w dowolnej chwili na zamówienie danego procesu może być wykonywany co najwyżej jeden rozkaz kodu programu.
Proces jest czymś więcej niż zakodowanym programem z określoną bieżącą czynnością. Do procesu na ogół należą także: stos procesu przechowujący dane tymczasowe oraz sekcja danych zawierająca zmienne globalne. Program jest obiektem pasywnym, a proces - aktywnym, z licznikiem rozkazów określającym następny rozkaz do wykonania.
Wykonujący się proces zmienia stan. Stan procesu jest po części określony przez bieżącą czynność procesu. Wyróżnia się trzy stany procesu:
- aktywny - są wykonywane instrukcje
- czekający - proces czeka na wystąpienie jakiegoś zdarzenia (np. na zakończenie operacji we-wy)
- gotowy - proces czeka na przydział procesora.
Tylko jeden proces może być aktywny. Reszta jest czekająca lub gotowa.
13. Na czym polega współbieżne wykonywanie procesów? Zalety tego podejścia.
Procesy mogą działać w systemie współbieżnie. Oznacza to, że jednostka centralna dzieli swą moc obliczeniową między wiele procesów jednocześnie. Za dopuszczeniem współbieżnego wykonywania przemawia kilka powodów:
- Ponieważ zasoby sprzętowe komputera są ograniczone, trzeba więc je dzielić między wielu użytkowników.
- Ponieważ kilku użytkowników może być zainteresowanych tą samą informacją (np. plikiem), należy wytworzyć środowisko umożliwiające wspólny dostęp do zasobów.
- Aby przyśpieszyć wykonywanie zadania można podzielić je na podzadania i wykonywać równolegle, ale wymaga to wielu elementów przetwarzających, np. procesorów lub kanałów.
- Sprzyja to tworzeniu procesów modularnych
- Nawet indywidualny użytkownik może mieć wiele zadań do wykonania w jednym czasie. Może np. uaktywnić program antywirusowy, drukować dokument i grać w szachy z komputerem
Działania współbieżne, które wymagają kooperacji między procesami, potrzebują mechanizmu do synchronizacji i komunikacji procesów.
Mając dany zbiór współpracujących procesów sekwencyjnych, dzielących wspólne dane, należy zadbać o zachowanie wzajemnej wyłączności niektórych z ich działań. Główną wadą tych rozwiązań jest wymagane przez nie aktywne czekanie. Trudność tą można pokonać dzięki użyciu semaforów. Do ochrony przed błędami synchronizacji używa się różnych konstrukcji w językach wysokiego poziomu.
Komunikacja międzyprocesowa stanowi mechanizm umożliwiający procesom wzajemne informowanie się i synchronizowanie działań. Najlepszą komunikację międzyprocesową osiąga się za pomocą systemu komunikatów (np. w Windows).
14. Procesy niezależne, a współpracujące. Procesy lekkie (wątki).
Procesy wykonywane w systemie operacyjnym mogą być niezależne albo mogą ze sobą współpracować. Proces jest niezależny. jeśli nie może wpływać na zachowanie innych procesów ani inne procesy nie mogą na niego oddziaływać.Proces niezależny ma następujące właściwości :
- na jego stan nie wpływa w żaden sposób żaden inny proces;
- jego działanie jest deterministyczne. tzn. wynik jego pracy zależy wyłącznie od stanu wejściowego;
- jego działanie daje się powielać. tzn. wynik pracy procesu niezależnego jest zawsze taki sam przy takich samych danych;
- jego wykonanie może być wstrzymywane i wznawiane bez żadnych szkodliwych skutków.
Każdy proces.który nie dzieli żadnych danych (tymczasowych lub trwałych) z żadnym innym procesem. jest w istocie procesem niezależnym. Proces jest współpracujący. jeśli oddziałuje na inne procesy w systemie lub może ulegać ich wpływom.Proces taki ma następujące właściwości :
- jego stan jest dzielony wraz z innymi procesami;
- nie da się określić z góry wyniku działania procesu.ponieważ zależy on od względnej kolejności jego wykonywania;
- wynik działania procesu współpracującego jest niedeterministyczny. gdyż może nie być zawsze taki sam przy tych samych danych wejściowych.
Dowolny proces. który dzieli jakieś dane z innymi procesami jest procesem współpracującym.Mogą one bezpośrednio dzielić przestrzeń adresów logicznych (tj. zarówno kod. jak i dane) lub może im być wolno dzielić dane wyłącznie za pośrednictwem plików.
Systemowa funkcja FORK powoduje podjęcie nowego wątku sterowania. przebiegającego w obrębie tej samej wirtualnej przestrzeni adresowej. Kilka nowych systemów operacyjnych realizuje ją w postaci mechanizmu wątków. Wątek jest jednostką podstawową wykorzystania procesora. Stan wątku jest zdefiniowany małą ilością odrębnych danych. Grupa równoprawnych wątków dzieli kod. przestrzeń adresową i zasoby systemu operacyjnego. Środowisko. w którym działa wątek. nazywa się zadaniem (ang. task). (Ciężki) proces jest równoważny zadaniu z tylko jednym wątkiem. Zadanie nic nie robi. jeśli nie ma w nim ani jednego wątku. z kolei wątek może przebiegać w dokładnie jednym zadaniu. Pojedynczy wątek ma przynajmniej własny stan rejestrów i na ogół własny stos. Konstrukcja grupy lekkich procesów polega na tym, że wiele wątków sterowania jest powiązanych z kilkoma zasobami dzielonymi.
Wątki mogą być obsługiwane przez jądro (np. systemy operacyjne Mach i OS/2). Tu systemy zawierają zbiór funkcji podobnych do tych. które obsługują procesy. Inne podejście polega tworzeniu wątków powyżej jądra systemu za pomocą zbioru funkcji bibliotecznych wykonywanych na poziomie użytkownika (np. w systemie Andrew).
15. Jakiego typu kolejki planowania związane są z obsługą procesów?
Procesy, które rezydują w tej pamięci, są gotowe do wykonania i na nie oczekują, znajdują się na liście zwanej kolejką procesów gotowych. Jest to na ogół lista z powiązaniami. Nagłówek kolejki procesów gotowych zawiera wskaźniki do pierwszego i ostatniego bloku kontrolnego procesu na liście. Każdy blok kontrolny procesu ma pole wskaźnikowe. wskazujące na następną pozycję w kolejce procesów gotowych. W systemie są również inne kolejki.Kiedy proces otrzymuje procesor. wtedy działa przez chwile. po czym albo kończy działanie. albo zaczyna oczekiwać na wystąpienie jakiegoś specjalnego zdarzenia. powiedzmy na zakończenie operacji wejścia - wyjścia. W przypadku zamówienia na operację wej-wyj może to być. np. prośba o dostęp do osobnego przewijaka taśmy lub do urządzenia dzielonego.takiego jak dysk. Dysk może być zajęty przez inne procesy. dlatego dany proces musi poczekać na dysk. Lista procesów czekających na konkretne urządzenie zwie się kolejką do urządzeń. Każde urządzenie ma własną kolejkę. W kolejce do urządzenia przeznaczonego do wyłącznego użytku. jak wspomniany przewijak taśmy. nie występuje nigdy więcej niż jeden proces. Jeśli urządzenie jest współdzielone - jak dysk - to w kolejce do niego może znajdować się wiele procesów. Diagram kolejek to typowa reprezentacja. ułatwiająca omawianie planowania procesów. Występują dwa typy kolejek :
- kolejka procesów gotowych;
- zbiór kolejek do urządzeń.
Nowy proces jest na początku umieszczany w kolejce procesów gotowych. Oczekuje w niej do czasu. aż zostanie wybrany do wykonania i otrzyma procesor. po czym może wystąpić jedno z kilku zdarzeń:
- proces może wydać zamówienie na operację wej-wyj i może zostać umieszczony w kolejce procesów oczekujących na wej-wyj;
- proces może utworzyć nowy proces i oczekiwać na jego zakończenie;
- proces może zostać przymusowo usunięty z procesora w wyniku przerwania i przeniesiony z powrotem do kolejki procesów gotowych.
W pierwszych dwóch przypadkach proces zostanie w końcu przełączony ze stanu oczekiwania do stanu gotowości i przeniesiony do kolejki procesów gotowych. W tym cyklu proces kontynuuje działanie aż do zakończenia. po czym będzie usunięty z systemu.
16. Podstawowe typy planistów obsługi kolejek procesów.
Proces wędruje między różnymi kolejkami przez cały czas swego istnienia. System operacyjny musi w jakiś sposób wybierać procesy z tych kolejek.
Selekcji dokonuje odpowiedni proces sytemu zwany planistą.
W systemie wsadowym często występuje więcej procesów. niż można by ich natychmiast wykonać. Procesy te są przechowywane w urządzeniach pamięci masowej (zazwyczaj na dyskach), gdzie oczekują na późniejsze wykonanie. Planista długoterminowy (lub planista zadań) wybiera procesy z tej puli i ładuje do pamięci w celu wykonania. Planista krótkoterminowy (lub planista przydziału procesora) wybiera jeden proces spośród procesów gotowych do wykonania i przydziela mu procesor.
Podstawową różnicą między obydwoma planistami jest częstotliwość ich uaktywnień. Planista krótkoterminowy musi bardzo często wybierać nowy proces dla procesora. Proces może działać zaledwie kilka milisekund. a potem przejść w stan oczekiwania. wydawszy zamówienie na operację wej-wyj. Często planista krótkoterminowy podejmuje działanie co najmniej raz na każde 10 ms. Ze względu na krótkie odcinki czasu między kolejnymi wykonaniami. planista krótkoterminowy musi być bardzo szybki. Jeśli decyzja o wykonaniu procesu przez 10 ms.. zabiera 1 ms.. to 1/(10+1) =9 procent pracy jest zużywane (marnowane) na samo zaplanowanie działania. Natomiast planista długoterminowy działa o wiele rzadziej. Między utworzeniem nowych procesorów w systemie mogą upływać minuty. Planista długoterminowy nadzoruje stopień wieloprogramowości. Jeśli stopień wieloprogramowości (liczba procesów w pamięci) jest stabilny. to średnia liczba utworzonych procesów musi się równać średniej liczbie procesów usuwanych z systemu. Toteż planista długoterminowy może być wywoływany tylko wtedy. gdy jakiś proces opuszcza system. Wskutek dłuższych przerw między wykonaniami planista długoterminowy może mieć więcej czasu na rozstrzyganie. który proces należy wybrać do wykonania.
Jest ważne. aby planista długoterminowy wybierał zarówno procesy ograniczone przez wej-wyj. jak i ograniczone przez dostęp do procesora. Jeśli wszystkie procesy są ograniczone przez wej-wyj. to kolejka procesów gotowych będzie prawie zawsze pusta i planista krótkoterminowy będzie miał za mało do roboty.
Najlepiej zachowuje się system. w którym jest zachowana właściwa proporcja procesów ograniczonych przez wej-wyj i przez procesor. Planista długoterminowy może być w niektórych systemach nieobecny lub mocno zredukowany. Np. systemy z podziałem czasu często nie mają żadnego planisty długoterminowego i umieszczają każdy nowy proces w pamięci pod opieką planisty krótkoterminowego. Stabilność tych systemów zależy od:
- fizycznych ograniczeń np. ograniczona liczba dostępnych końcówek konwersacyjnych;
- od zdolności adaptacyjnych użytkowników.
W niektórych systemach operacyjnych. takich jak systemy z podziałem czasu. mogą występować dodatkowe - pośrednie poziomy planowania (planista średnioterminowy).
Za użyciem tego planisty przemawia fakt. że niekiedy może okazać się korzystne usunięcie procesów z pamięci. w celu zmniejszenia stopnia wieloprogramowości. Usunięte procesy można później znów wprowadzić do pamięci. a ich wykonanie kontynuować od tych miejsc, w których je przerwano. Postępowanie takie jest często nazywane wymianą. Proces jest wymieniany, czyli wysyłany z pamięci operacyjnej na zewnątrz i później wprowadzany do niej ponownie przez planistę średnioterminowego.
17. Co to jest cykl zatrudnień procesor-urządzenie? Omów jego związek z algorytmem planowania.
Planowanie to jedna z podstawowych funkcji systemu operacyjnego. Prawie wszystkie zasoby komputera przydzielane są wg określonego planu. Ponieważ procesor jest jednym z najważniejszych elementów komputera, to planowanie jego wykorzystania ma zasadnicze znaczenie w projektowaniu systemu operacyjnego.
Charakterystyczną właściwością procesów jest to, że wykonanie procesu składa się z następujących po sobie cykli działania procesora i oczekiwania na urządzenie zewnętrzne. Każdy taki cykl nazywamy cyklem zatrudnień procesor-urządzenie. Proces naprzemiennie przechodzi od stanu działania procesora do stanu oczekiwania na urządzenie zew. Wykonanie procesu rozpoczyna się od fazy procesora, po której następuje faza we-wy. Następnie proces znowu przechodzi do fazy procesora poczym ponownie do fazy we-wy itd. W ostatniej fazie procesora, proces składa w systemie zamówienie na zakończenie swojego działania. Planowanie przydziału procesora związane jest z zagadnieniem podjęcia decyzji o tym, którym procesom z kolejki procesów gotowych, ma być przydzielony procesor centralny. Bardzo duże znaczenie przy dobieraniu algorytmu planowania przydziału procesora mają wyniki przeprowadzonych pomiarów okresów zatrudnień procesora. Wyniki te różnią się oczywiście w zależności od procesu i samego systemu komputerowego.
Generalnie jednak wskazują one, że istnieje dużo bardzo krótkich faz procesora i mało faz bardzo długich. Program ograniczony przez we-wy ma zwykle dużo krótkich faz procesora, natomiast program ograniczony przez procesor ma mało faz procesora, fazy te są jednak bardzo długie.
18. Na czym polega różnica pomiędzy wywłaszczeniowym a niewywłaszczeniowym schematem planowania?
Planowanie to jedna z podstawowych funkcji systemu operacyjnego. Prawie wszystkie zasoby komputera przydzielane są wg określonego planu. Ponieważ procesor jest jednym z najważniejszych elementów komputera, to planowanie jego wykorzystania ma zasadnicze znaczenie w projektowaniu systemu operacyjnego. Planowanie przydziału procesora związane jest z zagadnieniem podjęcia decyzji o tym, którym procesom z kolejki procesów gotowych, ma być przydzielony procesor centralny. Decyzje o przydziale procesora mogą zapadać w następujących przypadkach:
1. Proces przeszedł do stanu czekania, np. z powodu zamówienia na we-wy lub czekania na zakończenie działania któregoś z procesów potomnych.
2. Proces przeszedł od stanu wykonywania do stanu gotowości, np. na skutek wystąpienia przerwania.
3. Proces przeszedł od stanu czekania do stanu gotowości, np. po zakończeniu operacji we-wy.
4. Proces zakończył działanie.
W przypadku wystąpienia sytuacji 1 lub 4 system operacyjny nie ma możliwości wyboru. Procesor przydzielony zostanie nowemu procesowi ( jeżeli znajduje się taki w kolejce procesów gotowych ). Mówimy wówczas o niewywłaszczeniowym schemacie planowania.
W przypadku sytuacji 2 i 3 algorytm planowania jest wywłaszczeniowy. W przypadku planowania bez wywłaszczeń proces tak długo korzysta z procesora dopóki nie zwolni go z powodu swojego zakończenia lub przejścia do stanu czekania.
19. Przełączanie kontekstu a program koordynujący.
Przy przełączaniu procesora do innego procesu niezbędne jest przechowanie stanu starego procesu i załadowanie przechowywanego stanu nowego procesu. Czynność ta nazywa się przełączaniem kontekstu. Czasy przełączania kontekstu są silnie uzależnione od właściwości sprzętu. W przypadku gdy procesor ma kilka zbiorów rejestrów, przełączanie kontekstu sprowadza się do zmiany wartości wskaźnika do bieżącego zbioru rejestrów. Jeżeli procesów jest więcej niż zbiorów rejestrów to system kopiuje stan rejestrów do i z pamięci. Im bardziej złożony jest sam system operacyjny tym więcej operacji trzeba wykonać przy przełączaniu kontekstu. Wykonanie wszystkich czynności związanych z przełączaniem kontekstu należy do obowiązków programu koordynującego. Program koordynujący to moduł systemu operacyjnego, który faktycznie przekazuje sterowanie procesora do procesu wybranego wcześniej przez krótkoterminowego planistę. Do zadań programu koordynującego należy:
- przełączanie kontekstu,
- przełączanie do trybu użytkownika,
- wykonanie skoku do odpowiedniego adresu w programie użytkownika w celu wznowienia działania programu.
20. Kryteria oceny algorytmów planowania.
Zagadnienie podjęcia decyzji o tym, którym procesom z kolejki procesów gotowych ma być przydzielony procesor centralny nazywamy planowaniem przydziału procesora. Różne algorytmy planowania mają różne właściwości i mogą być lepiej dostosowane do pewnych klas procesów, a gorzej do innych. Do porównywania algorytmów planowania przydziału procesora stosuje się kilka kryteriów, z których najważniejsze omówione są poniżej.
1) Wykorzystanie procesora - kryterium określa ile czasu procesor jest zajęty pracą (0 - 100%). Dąży się oczywiście do tego, aby procesor był nieustannie zajęty. W systemach rzeczywistych wykorzystanie procesora powinno wahać się od 40% (słabe) do 90% (intensywna eksploatacja systemu)
2) Przepustowość - jest to liczba procesów kończonych w jednostce czasu. Dla długich procesów wartość ta może wynosić 1 proces/1h, dla krótkich transakcji przepustowość może się kształtować na poziomie 10p/1s.
3) Czas cyklu przetwarzania - jest to czas potrzebny na wykonanie danego procesu. Ściślej rzecz biorąc jest to czas upływający między chwilą nadejścia procesu do systemu a chwilą zakończenia go. CCP jest sumą okresów spędzonych na czekaniu na wejście do pamięci, czekaniu w kolejce procesów gotowych do wykonania, wykonywaniu procesu przez procesor i wykonywaniu operacji we/wy.
4) Czas oczekiwania - algorytmy planowania mają wpływ tylko na czas jaki proces spędza w kolejce procesów gotowych do wykonania (nie ma zaś wpływu na czas wykonania procesu [m.in. szybkość procesora] ani na oper. we/wy). Tak więc zamiast brać pod uwagę czas cyklu przetwarzania można ograniczyć się do rozważenia czasu oczekiwania każdego procesu.
5) Czas odpowiedzi - Czas cyklu przetwarzania jest na ogół uzależniony od prędkości urządzenia wyjściowego (w syst. interakcyjnych proces może wyprodukować oczekiwane wyniki dość wcześnie i przejść do dalszych obliczeń podczas gdy poprzednie wyniki są prezentowane użytkownikowi). Dlatego też wprowadzono kryterium czasu odpowiedzi - czas upływający między przedłożeniem zamówienia a pojawieniem się pierwszej odpowiedzi
Wykorzystując powyższe kryteria dąży się do maksymalizacji wykorzystania procesora i zwiększenia przepustowości oraz do minimalizacji CCP, oczekiwania i czasu odpowiedzi. W większości przypadków optymalizuje się miarę średnią lecz w niektórych sytuacjach bardziej pożądane jest zmaksymalizowanie jednej z wymienionych cech algorytmu planowania. Np. gdy chcemy zadbać o jak najlepszą obsługę wszystkich użytkowników zmniejszamy maksymalny czas odpowiedzi itd.
21. Podstawowe algorytmy planowania.
I. Najprostszym algorytmem jest FCFS - „pierwszy nadszedł - pierwszy obsłużony”. Według tego algorytmu proces, który pierwszy zamówi procesor -pierwszy go otrzyma. W praktyce algorytm ten realizuje się za pomocą kolejki FIFO. Blok kontrolny procesu wchodzącego do kolejki procesów gotowych dołączany jest do końca kolejki. Wolny procesor przydziela się procesowi z czoła kolejki. Wadą FCFS jest długi średni czas oczekiwania. Dal przykładu dla zbioru procesów nadchodzących w chwili 0 o następujących długościach faz w ms : P1 - 24, P2 - 3, P3 - 3 i takiej jak wymieniona kolejności, zostaną one obsłużone w kolejności P1, P2, P3. Czas oczekiwania dla P1 = 0, dla P2 = 24 i P3 = 27. Zatem średni czas oczekiwania wynosi (0 + 24 + 27)/3 = 17. Gdyby procesy nadeszły w kolejności P2, P3, P1 to ŚCO = (0 + 3 + 6)/3 = 3. Jak widać dla niektórych przypadków algorytm FCFS może być bardzo nieefektywny bo jego ŚCO wykazuje znaczne wahania dla procesów o rozmaitej długości faz procesora. Algorytm FCFS jest niewywłaszczający. Po objęciu kontroli nad procesorem proces utrzymuje ją aż do zakończenia swego działania albo żądania oper. we/wy. FCFS jest szczególnie nieefektywny w systemach z podziałem czasu, w których ważne jest, aby każdy użytkownik dostawał przydział procesora w regularnych odstępach. Pozwolenie jakiemuś procesowi na zajmowanie procesora przez dłuższy czas byłoby w tych warunkach katastrofalne.
II. Algorytm SJF - „najpierw najkrótsze zadanie” - algorytm ten wiąże z każdym procesem długość jego najbliższej z przyszłych faz procesora. Procesor zostaje przydzielony procesowi mającemu najkrótszą najbliższą fazę procesora. Jeżeli dwa procesy mają tak samo długie fazy stosuje się FCFS. Rozpatrzmy zbiór procesów: P1 - 6, P2 - 8, P3 - 7, P4 - 3. Zgodnie z SJF procesu wykonają się w kolejności P4, P1, P3, P2. Średni czas oczekiwania wynosi (0 + 3 + 9 +16)/4=7. Dla FCFS ŚCO=10.25 ms. Algorytm SJF jest optymalny tzn. daje minimalny średni czas oczekiwania dla danego procesu. Największą trudność w praktycznej realizacji SJF stanowi określenie długości następnego zamówienia na przydział procesora. Dlatego też używany jest on w planowaniu zadań (czyli długoterminowym). Nie może być natomiast zaimplementowany na poziomie krótkoterminowego planowania przydziału procesora ponieważ nie ma sposobu na poznanie długości następnej fazy procesora. Pewną radą jest próba jej przybliżenia, oszacowania. Zakłada się, że długość następnej fazy będzie podobna do długości faz poprzednich. Obliczając przybliżenie długości następnej fazy, można wybrać proces z najkrótszą przewidywaną fazą procesora. Algorytm SJF może być wywłaszczający lub niewywłaszczający. Załóżmy, że w kolejce procesów gotowych do wykonania pojawia się nowy proces, a poprzedni jeszcze używa procesora. Ponadto nowy proces ma krótszą fazę procesora, niż to, co pozostało do wykonania w procesie bieżącym. Wywłaszczający SJF usunie w tej sytuacji dotychczasowy proces, podczas gdy niewywłaszczający pozwoli bieżącemu na zakończenie fazy procesora.
III. Planowanie priorytetowe - każdemu procesowi przypisuje się pewien priorytet, po czym przydziela się procesor procesowi o priorytecie najwyższym. Opisany wcześniej algorytm SJF jest alg. priorytetowym, w którym priorytet p jest odwrotnością następnej fazy procesora t. Rozważmy zbiór procesów przybyłych w czasie 0 o następującym czasie trwania fazy i priorytecie: P1-10 ms - p=3; P2-1-1; P3-2-3; P4-1-4; P5-5-2. Przy użyciu planowania priorytetowego procesu wykonają się w kolejności P2, P5, P1, P3, P4. ŚCO = 8,2. Planowanie priorytetowe może być wywłaszczające lub niewywłaszczające (patrz dla algorytmu SJF). Podstawowym problemem w planowaniu priorytetowym jest tzw. nieskończone blokowanie. W mocno obciążonych systemach komputerowych proces o bardzo niskim priorytecie może teoretycznie oczekiwać na przydzielenie procesora w nieskończoność. Rozwiązaniem tego problemu jest postarzanie procesów. Polega ono na podwyższaniu priorytetów procesów długo oczekujących w systemie. Musi to prowadzić w efekcie do wykonania procesów o nawet bardzo niskim początkowym priorytecie.
IV. Planowanie rotacyjne - zaprojektowano je dla systemów z podziałem czasu. Ustala się małą jednostkę czasu - kwant czasu (10-100 ms). Kolejka procesów gotowych do wykonania jest traktowana jak kolejka cykliczna. Planista każdemu procesowi przydziela odcinek czasu nie dłuższy niż kwant czasu. Kolejkę procesów prowadzi się zgodnie z zasadami FIFO. Pobierany jest proces z czoła kolejki. Gdy ma on fazę procesora krótszą niż 1 kwant wtedy proces z własnej inicjatywy zwolni procesor i pobierany jest następny proces z czoła kolejki. W przeciwnym wypadku, jeżeli proces ma fazę dłuższą niż 1 kwant dokonuje się przełączenie kontekstu i proces zostaje odłożony na koniec kolejki. Wadą tego planowania jest z reguły duży ŚCO. Rozważmy sytuację dla procesów przybyłych w chwili 0 i następujących długościach faz: P1 - 24, P2 - 3, P3 - 3. Kwant - 4ms. Procesor zostanie przydzielony P1, po 4ms P2, który potrzebuje 3ms, czyli mniej niż wynosi kwant. Po 3ms P2 zwolni procesor, który zostanie przydzielony P3. Sytuacja powtórzy się i następnie procesor przydzielony zostanie P1, któremu zostało 20ms, a więc zostanie mu przydzielone następne 5 kwantów czasu. Planowanie rotacyjne jest wywłaszczeniowe. Jeżeli kwant czasu jest dostatecznie mały (np. 0.001 ms) mamy do czynienia z dzieleniem procesora. Sprawia to na użytkowniku wrażenie, że każdy z n procesów ma własny procesor działający z 1/n prędkości rzeczywistego procesora. Przy planowaniu rotacyjnym duże znaczenie ma także czas przełączania kontekstu. Jest wskazane aby kwant czasu był długi w porównaniu do czasu przełączania kontekstu. Można też zauważyć, że jeżeli kwant czasu jest zbyt duży, planowanie rotacyjne przechodzi w FCFS. Z tego względu poleca się stosować regułę, że 80% faz procesora powinno być krótszych niż jeden kwant czasu.
Uwaga!!! Odpowiedzi na pytania 22 i 23 są umieszczone w jednym punkcie gdyż ściśle wiążą się ze sobą.
22.Na podstawie dowolnego przykładu sformułować problem producent - konsument.
23. Co to jest przeplot? Przedstawić problemy wynikające z przeplotu przy współbieżnym wykonywaniu procesów.
Podstawą wieloprogramowych systemów operacyjnych jest przetwarzanie współbieżne. Aby procesy mogły być wykonywane w uporządkowany sposób w systemie muszą znajdować się mechanizmy do synchronizowania i komunikowania się procesów. Układ procesów producent-konsument jest powszechnie spotykany w systemach operacyjnych złożonych z pewnej liczby współpracujących procesów sekwencyjnych, wykonywanych asynchronicznie i ewentualnie dzielących dane. Proces producent wytwarza informację, którą zużywa konsument. Np. program drukujący wytwarza znaki, które są pobierane przez program obsługi drukarki, kompilator produkuje kod asemblerowy który jest „konsumowany” przez asembler. Z kolei asembler może wytwarzać moduły programu wynikowego „konsumowane” przez program ładujący. Aby umożliwić producentowi i konsumentowi działanie współbieżne należy założyć pulę buforów, które producent będzie zapełniać, konsument zaś opróżniać. Producent może odsyłać wyniki do jednego bufora, podczas gdy konsument pobiera dane z innego buforu. Procesy producenta i konsumenta muszą podlegać synchronizacji, aby konsument nie próbował konsumować jednostek, które nie zostały jeszcze wyprodukowane. W zagadnieniu koordynacji procesów producenta i konsumenta z nieograniczonym buforem nie ma żadnych praktycznych ograniczeń na liczbę buforów. Może się zdarzyć, że konsument musi czekać na nowe jednostki, ale producent może je produkować nieustannie - zawsze istnieją puste bufory. W zagadnieniu z ograniczonym buforem zakłada się, że liczba buforów jest ustalona. W tym przypadku konsument musi czekać, jeśli wszystkie bufory są puste, a producent musi czekać, jeżeli wszystkie bufory są zapełnione. Poniżej przedstawione jest jedno z rozwiązań zagadnienia z ograniczonym buforem. Algorytm ten przedstawi nam jednocześnie problem przeplotu. Dwa procesy producent i konsument dzielą następujące dane (zmienne):
n - ilość buforów danych; bufor: array [0..n-1] of JakiśTyp - te właśnie bufory;
we: 0..n-1 - wskazuje na następny pusty bufor; wy: 0..n-1 - pierwszy zajęty bufor;
licznik - zmienna ta będzie zwiększana, gdy do puli dołączany będzie pełny bufor i zmniejszana gdy z puli będzie zabierany jakiś pełny bufor; zmpom - zmienna pomocnicza typu JakiśTyp.
Zmienne we i wy oraz licznik mają wartości początkowe 0. Pula jest pusta gdy we = wy i pełna gdy (we+1) mod n = wy.
Kody procesów producenta i konsumenta przedstawiają się następująco:
Producent: Konsument:
repeat repeat
... while licznik = 0 do nicnierób;
produkuj jednostkę w zmpom; zmpom := bufor[wy];
... wy := (wy + 1) mod n;
while licznik = n do nic_nie_rób; licznik := licznik -1;
bufor[we] := zmpom; ...
we := (we + 1) mod n; konsumowanie jednostki z zmpom
licznik := licznik + 1; ...
until false; until false;
Obie procedury są poprawne jeżeli są rozpatrywane z osobna. Jednak mogą działać niewłaściwie gdy będą wykonywane współbieżnie. Wiąże się to ze zjawiskiem przeplotu. Załóżmy, że licznik = 5 oraz, że producent i konsument wykonują współbieżnie (w tej samej chwili) instrukcje licznik := licznik +1; i licznik := licznik -1;. Po wykonaniu tych dwu instrukcji wartość zmiennej licznik może wynieść 4, 5 lub 6. Poprawny jest natomiast tylko wynik 5. Mechanizm tego zjawiska jest następujący. Wspomniane instrukcje mogą być przetłumaczone na kod maszynowy jako ciąg rozkazów:
rejestr1 := licznik; rejestr2 := licznik;
rejestr1 := rejestr1+1; rejestr2 := rejestr2-1;
licznik := rejestr1; licznik := rejestr2;
przy czym rejestr1 i rejestr2 to lokalne rejestry procesora. Nawet jeśli byłby to ten sam rejestr fizyczny (np. akumulator), to należy pamiętać, że zawartość takiego rejestru podlega przechowaniu i odtwarzaniu przez procedurę obsługi przerwań. Współbieżne wykonywanie instrukcji: inc(licznik) i dec(licznik) jest równoważne wykonaniu sekwencyjnemu, w którym podane powyżej rozkazy w języku maszynowym mogą się przeplatać w dowolnym porządku. Jednym z takich przeplotów może być:
I1: producent: wykonaj rejestr1 := licznik {rejestr1 = 5}
I2: producent: wykonaj rejestr:= rejestr1+1 {rejestr1 = 6}
I2: konsument: wykonaj rejestr2 := licznik {rejestr2 = 5}
I4: konsument: wykonaj rejestr2 := rejestr2-1 {rejestr2 = 4}
I5: producent: wykonaj licznik := rejestr1 {licznik = 6}
I6 :konsument: wykonaj licznik := rejestr2 {licznik = 4}
Zauważmy, że otrzymujemy niepoprawny stan licznik=4, znamionujący istnienie 4 pełnych buforów, podczas gdy faktycznie jest ich 5. Gdyby odwrócić kolejność instrukcji I5 i I6, otrzymany stan byłby również niepoprawny i wynosił licznik=6. Przyczyną powstawania błędów jest powstawanie przeplotu poprzez zezwolenie na to, aby oba procesy manipulowały zmienna licznik współbieżnie. W celu usunięcia tej trudności trzeba zagwarantować, że tylko jeden proces w danym czasie może operować na tej zmiennej.
24. Co to jest sekcja krytyczna i na czym polega jej rozwiązanie?
Niech będzie dany system złożony z N procesów. Każdy proces ma segment kodu, zwany sekcją krytyczną, w którym może zmieniać wspólne zmienne, aktualizować tablice itd. Ważną cechą tego systemu winna być zasada, że gdy jeden proces wykonuje sekcję krytyczną wówczas żaden inny proces nie może wykonywać swojej sekcji krytycznej (mogłoby wówczas dojść do przeplotu). Problem sekcji krytycznej polega na skonstruowaniu protokołu, który mógłby posłużyć do organizowania współpracy procesów. Każdy proces musi prosić o pozwolenie na wejście do swojej sekcji krytycznej. Niech fragment kodu implementującego taką prośbę nazywa się sekcją wejściową. Po sekcji krytycznej może występować sekcja wyjściowa. Pozostały kod niech nazywa się resztą. Zatem typowy proces wygląda następująco
repeat
sekcja wejściowa
sekcja krytyczna
sekcja wyjściowa
reszta
until false
Rozwiązanie problemu sekcji krytycznej musi spełniać trzy warunki:
1. Wzajemne wykluczanie - Jeżeli proces P1 działa w sekcji krytycznej, to żaden inny proces nie działa w sekcji krytycznej.
2. Postęp - Jeżeli żaden proces nie dziala w sekcji krytycznej oraz istnieją procesy, które chcą wejść do sekcji krytycznych, to tylko procesy nie wykonujące swoich reszt mogą kandydować do wejścia jako następne do sekcji krytycznych. Wybór ten nie może być odwlekany w nieskończoność.
3. Ograniczone czekanie - Musi istnieć wartość graniczna liczby wejść innych procesów do ich sekcji krytycznych po tym, gdy dany proces zgłosił chęć wejścia do sekcji krytycznej i zanim uzyskał na to pozwolenie.
Poniżej podam rozwiązanie sekcji krytycznej dla dwu procesów, spełniające wszystkie trzy założenia przy jeszcze dodatkowym, iż przedstawione rozkazy maszynowe są mimo współbieżności wykonywane niepodzielnie tzn. nie wystąpi zjawisko przeplotu.
Algorytm:
Niech procesy dzielą następujące zmienne: zmienna całkowita numer której wartość na początku jest nieistotna ( ale wynosi 0 lub 1); flaga: array[0..1] of boolean - na początku flaga[0] = flaga[1] = false. Struktura procesu Pi jest następująca:
repeat
flaga[i] := true; }
numer := j; } sekcja wejściowa
while (flaga[j] and numer = j) do nic_nie_rób; }
sekcja krytyczna
flaga[i] := false; } sekcja wyjściowa
reszta
until false;
Aby wejść do sekcji krytycznej proces Pi najpierw nadaje zmiennej flaga[i] wartość true, po czym zakłada, że również drugi proces chce wejść do sekcji krytycznej, jeśli to będzie możliwe (numer = j). Jeśli oba procesy próbują wejść w tym samym czasie, zmienna numer otrzyma zarówno wartość i jak i wartość j prawie w tym samym czasie. Tylko jedno z tych przypisań nada wartość zmiennej; drugie pojawi się lecz zostanie natychmiast zastąpione nowym. Ostateczna wartość zmiennej numer zadecyduje o tym, któremu z dwu procesów przypadnie w udziale prawo do wejścia do sekcji krytycznej w pierwszej kolejności.
25. i 26. Omówić problem wzajemnego wykluczania oraz własności żywotności procesów (blokada, zagłodzenie). Przedstawić dowolną próbę rozwiązania problemu wzajemnego wykluczania. Omów jej wady i zalety. Wykaż, że jest poprawna lub błędna.
Problem wzajemnego wykluczania pojawia się w systemie w momencie gdy istnieje w nim choć jeden zasób niepodzielny; to znaczy, że zasobu tego może używać w danym czasie tylko jeden proces. Jeżeli inny proces zamawia dany zasób, to proces ten musi być opóźniany do czasu, aż zasób zostanie zwolniony. Na przykład drukarka nie może być jednocześnie użytkowana przez kilka procesów (w przeciwieństwie np. do pliku tylko do odczytu - jeśli kilka procesów chce w tym samym czasie otworzyć taki plik, to zezwoli się im na jednoczesne korzystanie z niego. Na zasób dzielony proces nigdy nie musi czekać). Problem wzajemnego wykluczania można omówić na przykładzie sekcji krytycznej procesu. Sekcja krytyczna procesu to fragment kodu, w którym każdy z procesów przechowuje wspólne zmienne. Jeżeli procesu będą mogły korzystać z tych zmiennych współbieżnie, to dane mogą ulec przekłamaniu (patrz - przeplot pyt. 23). Aby tego uniknąć należy uczynić sekcję krytyczną zasobem niepodzielnym, a co za tym idzie należy zaimplementować mechanizm wzajemnego wykluczania - jeśli proces P1 działa w sekcji krytycznej, to żaden inny proces nie działa w sekcji krytycznej. Poniżej przedstawię algorytm rozwiązujący problem wzajemnego wykluczania dla sekcji krytycznej (dla dwóch procesów).
Niech dwa procesu dzielą wspólną zmienną całkowitą numer, przyjmującą na początku wartość 0 lub 1. Kod procesu Pi przedstawia się jak niżej:
repeat
while numer <> i do nic_nie_rób;
sekcja krytyczna
numer := j;
reszta
until false
Proces Pi ma pozwolenia na pracę w sekcji krytyczne tylko w wypadku gdy numer=i. Dla dwóch procesów jeżeli numer=1 w sekcji krytyczne działa proces P1, w przeciwnym wypadku (numer=2) w sekcji krytycznej działa proces P2. Rozwiązanie to jest poprawne z punktu widzenia wzajemnego wykluczania, ponieważ gwarantuje, iż tylko jeden proces w danym czasie może znaleźć się w sekcji krytycznej. Wadą tego algorytmu jest to, iż narzuca on zwykłe naprzemienne wykonywanie przez procesy sekcji krytycznej. Np., jeśli numer=1 i proces P2 jest gotowy do wejścia do sekcji krytycznej, to nie będzie mógł tego uczynić, nawet wówczas, gdy proces P1 może już wykonywać sekcję reszty.
Sytuację, w której kilka procesów czeka w nieskończoność na zdarzenie, które może powstać tylko wskutek działania jednego z nich nazywamy blokadą. Zdarzenia, o które głównie tu chodzi, to najczęściej pozyskiwanie i zwalnianie zasobów. Stan blokady przedstawię na przykładzie systemu złożonego z dwu procesów, P0 i P1, z których każdy ma dostęp do dwu semaforów, S i Q, ustawionych na 1 (pojęcie semaforu szczegółowo wyjaśnione jest w pkt. 28). Niech operacje wykonywane przez P0 i P1 są następujące:
P0 P1
czekaj(S); czekaj(Q);
czekaj(Q); czekaj(S);
... ...
sygnalizuj(S); sygnalizuj(Q);
sygnalizuj(Q); sygnalizuj(S);
Załóżmy, że proces P0 wykona operację czekaj(S), a potem proces P1 wykona operację czekaj(Q). Kiedy proces P0 przejdzie do wykonania operacji czekaj(Q), wtedy będzie musiał czekać, aż proces P1 wykona operację sygnalizuj(Q). Podobnie, gdy proces P1 wykona operację czekaj(S), rozpocznie wówczas czekanie na to, aby proces P0 wykonał operację sygnalizuj(S). Ponieważ operację sygnalizacji nie mogą już być wykonane, więc procesy P0 i P1 są zablokowane.
Innym problemem związanym z blokadami jest blokowanie nieskończone zwane głodzeniem. Jest to sytuacja, w której procesu czekają w nieskończoność pod semaforem. Blokowanie nieskończone może powstać, jeśli przy dodawaniu i usuwaniu procesów z listy związanej z semaforem użyje się porządku LIFO. Głodzenie (czyli nieskończone oczekiwanie na zasoby) powstaje gdy wywłaszczanie dotyczy wciąż tego samego procesu. W systemie, w którym wybór wywłaszczanego procesu opiera się przede wszystkim na ocenie kosztów, może się zdarzyć, że w roli ofiary będzie wybierany wciąż ten sam proces. Wskutek tego proces nigdy nie zakończy swojej pracy - powstanie sytuacja głodzenia procesu, która będzie wymagała jakiegoś praktycznego rozwiązania. Mówiąc wprost, należy zapewnić, by proces mógł być wydelegowany do roli ofiary skończoną liczbę razy. Najpowszechniejszym rozwiązaniem jest uwzględnienie liczby wycofań przy ocenie kosztów.
27. Omów algorytm Dekkera rozwiązujący problem wzajemnego wykluczania się (dla dwóch procesów).
Następujący algorytm, opracowany przez Dekkera, jest pierwszym znanym, poprawnym rozwiązaniem problemu sekcji krytycznej dla dwu procesów. Dwa procesy, Po i P1, dzielą następujące zmienne:
var: flaga: array [0..1] of boolean; (* początkowo fałszywe *)
numer: 0..1;
Poniższy program dotyczy procesu Pi (i = 0 lub 1), przy czym Pj (j = 1 lub 0) oznacza drugi proces.
repeat
flaga[i] : = true;
while flaga[j] do
if numer = j then
begin
flaga[i] : = false;
while numer = j do nic;
flaga[i]:= true;
end;
sekcja krytyczna
numer:=j;
flaga[i] : = false;
reszta
until false;
Algorytm Dekkera służy do rozwiązywania problemu sekcji krytycznej. Sekcja krytyczna jest to obszar kodu, w którym proces może zmieniać wspólne zmienne, używać współdzielonych urządzeń itp. Trzeba jednak przestrzegać zasady, że tylko jeden proces może znajdować się w sekcji krytycznej. Tak więc procesy muszą wzajemnie wyłączać się w czasie. Problem sekcji krytycznej polega na stworzeniu metod organizujących współpracę procesów. Istnieje wiele metod obsługi problemu sekcji krytycznej. Do jednej z nich należy algorytm Dekkera.
Dzieli on kod na cztery zasadnicze etapy. Pierwszy z nich to sama sekcja krytyczna. Drugi jest nazywany sekcją wejściową. W sekcji wejściowej proces prosi o pozwolenie na wejście do swojej sekcji krytycznej. Trzeci etap jest określany jako sekcja wyjściowa. W tym fragmencie kodu proces informuje inne procesy o opuszczaniu sekcji krytycznej. Do czwartego etapu należy pozostały kod nazywany też resztą.
Rozwiązanie sekcji krytycznej musi spełniać następujące warunki:
1. Tylko jeden z procesów może w tym samym czasie działać w sekcji krytycznej.
2. Jeśli żaden proces nie jest w sekcji krytycznej, ale istnieją procesy chcące wejść do sekcji krytycznej, to kandydować do wejścia mogą jedynie procesy nie wykonujące swych reszt. Wybór procesu nie może być odwlekany w nieskończoność.
3. Musi istnieć określona ilość wejść innych procesów do sekcji krytycznej, gdy jeden proces zgłosił chęć wejścia do sekcji krytycznej i uzyskał na to pozwolenie.
Aby wejść do sekcji krytycznej i-ty proces zmienia wartość flaga[i] na True. Zmienna numer może mieć wartość jedynie i lub j. Decyduje to o tym, który proces wchodzi do sekcji krytycznej.
Warunek 1 jest spełniony. Proces może wejść do sekcji krytycznej tylko wtedy, gdy flaga[j]=False. Gdy drugi proces próbuje wejść do sekcji krytycznej (lub gdy się w niej znajduje) to flaga[j]=True i proces wykonuje pętlę while dopóki flaga[j]=True. W pętli while istnieje instrukcja if. Działa ona w zależności od wartości zmiennej numer. Gdy zmienna numer wskazuje na drugi proces to flaga[i] otrzymuje wartość False. Uwalnia to drugi proces z oczekiwania na wejście do sekcji krytycznej. Procesy nie mogą się więc zablokować w oczekiwaniu na wejście do sekcji krytycznej, a jednocześnie nie mogą być wykonywane oba ponieważ zmienna numer może mieć jedną wartość (0 lub 1)
Warunek 2 jest spełniony. Gdy proces Pi jest w sekcji krytycznej to flaga[i]=True. Jeśli flaga[j]=True, to proces Pj wykonuje pętlę while w oczekiwaniu na wejście do sekcji krytycznej. Proces Pi zaraz po wyjściu z sekcji krytycznej nada zmiennej numer wartość j i flaga[i]=False. Pozwoli to procesowi Pj na wejście do sekcji krytycznej, chociaż. on sam nie zmieni wartości zmiennej numer.
Warunek 3 jest spełniony. Gdy proces Pi wychodzi z sekcji krytycznej nadaje zmiennej numer wartość j i ustawie flaga[i] na False. Pozwala to na wejście do sekcji krytycznej procesowi Pj. A więc proces Pj wchodzi do sekcji krytycznej co najwyżej po jednym wejściu Pi.
Algorytm Dekkera spełnia więc problem wzajemnego wykluczania się procesów dla dwóch procesów. Można by zbudować algorytm dla wielu procesów, lecz byłby on trudniejszy do analizy i wykonania.
28. Omów pojęcie semafora i podstawowe operacje na nim.
Semafor jest to zmienna całkowita. Jest ona dostępna tylko dla dwóch niepodzielnych operacji: czekaj, sygnalizuj. Jednocześnie tylko jeden proces może modyfikować wartość semafora. Podczas sprawdzania semafora nie może też wystąpić przerwanie. Semafory stosuje się szczególnie do rozwiązywania problemu sekcji krytycznej dla n procesów. Dodatkowo stosuje się je także do rozwiązywania problemów synchronizacji. Użycie semaforów pozwala na efektywniejsze wykorzystanie procesora niż w przypadku algorytmu Dekkera. W algorytmie tym procesy chcące wejść do sekcji krytycznej wykonują ciągle instrukcje sekcji wejściowych, co powoduje jałowe użytkowanie procesora. Przy użyciu semaforów można ominąć operacje aktywnego czekania poprzez zablokowanie procesu i umieszczenie go w kolejce oczekujących procesów. Odblokowanie procesu następuje na skutek wołania operacji sygnalizuj przez inny proces. Wykonywana jest wtedy operacja budzenia zmieniająca stan procesu na gotowość. Proces przechodzi do kolejki procesów gotowych do wykonania.
Każdy semafor ma wartość całkowitą i listę procesów. Proces czekający pod semaforem jest dołączany do listy procesów. Operacja sygnalizuj usówa jeden proces z listy oczekujących i budzi go. Lista oczekujących procesów może być obsługiwana według różnych sposobów obsługi kolejek (FIFO, LIFO, kolejka priorytetowa).
Gwarancją poprawnego działania semaforów jest zapewnienie dostępu do semafora tylko jednemu procesowi. Można to osiągnąć na dwa sposoby. W środowisku jednoprocesorowym wystarczy zablokować wykrywanie przerwań podczas operacji sygnalizuj i czekaj. Nie można tego zastopsować w środowiskach wieloprocesorowych. Jeśli nie istnieją specjalne instrukcje sprzętowe to można zastosować tu dowolne rozwiązanie problemu sekcji krytycznej. Tak więc aktywne czekanie jest tutaj przesunięte z sekcji wyjściowych do operacji czekaj i sygnalizuj. Jednak operacje te są bardzo krótkie, a więc aktywne czekanie przestaje być odczuwane.
29. Wykorzystaj semafor do rozwiązania problemu wzajemnego wykluczania w wersji dla n procesów.
Mechanizm semaforów służy m.in. do rozwiązywania problemu sekcji krytycznej. Sekcja krytyczna jest to obszar kodu, w którym proces może zmieniać wspólne zmienne, używać współdzielonych urządzeń itp. Trzeba jednak przestrzegać zasady, że tylko jeden proces może znajdować się w sekcji krytycznej. Tak więc procesy muszą wzajemnie wyłączać się w czasie. Problem sekcji krytycznej polega na stworzeniu metod organizujących współpracę procesów. Istnieje wiele metod obsługi problemu sekcji krytycznej np. do jednej z nich należy algorytm Dekkera lub mechanizm semaforów.
Dzieli on kod na cztery zasadnicze etapy. Pierwszy z nich to sama sekcja krytyczna. Drugi jest to operacja czekaj. W operacji czekaj proces prosi o pozwolenie na wejście do swojej sekcji krytycznej następnie blokuje się i staje w kolejce procesów oczekujących. Trzeci etap jest to procedura sygnalizuj. Procedura ta powoduje obudzenie danego procesu z kolejki oczekujących i odpowiednie ustawienie wartości semafora. Do czwartego etapu należy pozostały kod nazywany też resztą.
Rozwiązanie sekcji krytycznej musi spełniać następujące warunki:
1. Tylko jeden z procesów może w tym samym czasie działać w sekcji krytycznej.
2. Jeśli żaden proces nie jest w sekcji krytycznej, ale istnieją procesy chcące wejść do sekcji krytycznej, to kandydować do wejścia mogą jedynie procesy nie wykonujące swych reszt. Wybór procesu nie może być odwlekany w nieskończoność.
3. Musi istnieć określona ilość wejść innych procesów do sekcji krytycznej, gdy jeden proces zgłosił chęć wejścia do sekcji krytycznej i uzyskał na to pozwolenie.
Semafor możemy zaimplementować np. tak:
typedef struct {
int stan;
listaProcesów *lista;
}semafor;
Na początku programu wartość stanu przyrównywana jest jedynce.
W procedurze void czekaj (semafor s ) zmniejszana jest wartość o jeden zmiennej stan. Następnie sprawdzany jest jej wartość, jeśli jest ona mniejsza od zera to następuje dołączenie danego procesu do listy procesów i wywołanie procedury blokującej.
W procedurze void sygnalizuj (semafor s) zwiększana jest wartość zmiennej stan o jeden. Jeśli zmienna stan jest mniejsza lub równa zero jeden z procesów zostaje usunięty z kolejki, a następnie obudzony.
30. Sformułuj problem pięciu filozofów i zaproponuj jego rozwiązanie przy użyciu semaforów. Przeanalizuj jego poprawność.
Problem posilających się filozofów jest standardowym zadaniem synchronizacji, które można odnieść szerokiego wachlarza innych problemów dotyczących sterowania współbieżnością. Problem ten można opisać za pomocą stołu, przy którym siedzi pięciu filozofów. Każdy filozof może w dowolnej chwili rozpocząć posiłek składający się z ryżu. Potrzebuje do tego dwóch pałeczek, które są rozmieszczone w specyficzny sposób. Każda pałeczka jest współdzielona z sąsiadem (każdy filozof współdzieli dwie pałeczki z dwoma sąsiadami) Jeśli filozof chce rozpocząć jedzenie musi zdobyć dwie pałeczki, leżące po obu stronach. Jeżeli któryś z jego sąsiadów jest w trakcie jedzenia, wtedy musi poczekać, aż tamten skończy jeść i odłoży pałeczki, co spowoduje udostępnienie ich głodnemu. Po zakończeniu jedzenia filozof odkłada obie pałeczki na stół. Odzwierciedla to konflikt dostęou do ograniczonych zasobów komputera (pałeczki) potrzebnych wielu procesom (filozofowie). Rozwiązanie problemu nie powinno dopuścić do zablokowania systemu (każdy filozof ma jedną pałeczkę) i nie powinno pozwolić na zagłodzenie filozofa.
Rozwiązując problem pięciu filozofów przy użyciu semaforów możemy użyć semaforów jako pałeczek natomiast filozofowie będą procesami. W przypadku takiego rozwiązania operacją czekaj będzie chęć wzięcia przez filozofa danej pałeczki. Natomiast odłożenie pałeczki będzie przedstawiane za pomocą operacji sygnalizuj. Należy więc zadeklarować tablicę o pięciu elementach typu semafor, które będą odzwierciedlać stan każdej z pałeczek. Na początku semafory są ustawione na wartość jeden. Sposób postępowania dowolnego filozofa można przedstawić w następujący sposób:
repeat
czekaj (pałeczka[i]);
czekaj (pałeczka[i+1 mod 5]);
jedzenie
sygnalizuj (pałeczka[i]);
sygnalizuj (pałeczka[i+1 mod 5]);
myślenie
until false;
Ten sposób rozwiązania problemu zapobiega sytuacji jedzenia przez dwóch sąsiadów jednocześnie. W przypadku gdyby wszyscy filozofowie zaczęli podnosić jedną pałeczkę, leżącą po tej samej stronie, to ulegli by zablokowaniu z powodu braku drugiej pałeczki, będącej w posiadaniu sąsiada. Można to rozwiązać uzależniając kolejność pobierania pałeczek od parzystości filozofa. Np. parzysty bierze najpierw lewą pałeczkę, a nieparzysty prawą. Można też uzależnić funkcję czekaj od obu pałeczek.
31. Co to jest monitor wykorzystywany do synchronizacji procesów?
Konstrukcją służącą do synchronizacji procesów w językach wysokiego poziomu jest monitor. Monitor operuje przy pomocy operacji zdefiniowanych przez programistę. Do określania stanu objektu służą zmienne zadeklarowane w monitorze. Do operacji na zmiennych monitora służą tylko procedury zdefiniowane w jego wnętrzu, co zapobiega bezpośredniemu dostępu do zmiennych monitora przez procesy. Budowa monitora powoduje, że w jego wnętrzu może być aktywny tylko jeden proces. Działa podobnie jak region krytyczny. W monitorach można deklarować zmienne typu warunek i jedynymi operacjami które mogą dotyczyć są operacje czekaj oraz sygnalizuj. Operacja x.czekaj - powoduje zawieszenie wywołującego ją procesu do pułki inny proces nie wywoła operacji x.sygnalizuj. Operacja x.sygnalizuj wznawia jeden z czekających procesów. Rozstrzygnięcie, który proces zostanie wznowiony jako pierwszy można zorganizować według dowolnego mechanizmu organizacji kolejki np. FCFS. Można jednak zastosować priorytety dla wstrzymanych procesów, a po wywołaniu procedury x.sygnalizuj wznawiany jest proces o najwyrzszym priorytecie. W przypadku kiedy nie ma żadnych procesów zawieszonych to operacja ta nie wykonuje żadnej instrukcji kiedy jest wywołana. W przypadku gdy proces A wywoła operacje x.sygnalizuj, a zawieszony jest proces B (równierz związany z warunkiem x), to proces B może wznowić działanie tylko wtedy gdy sygnalizujący proces A będzie musiał czekać. Gdyby tak się niestało procesy A i B byłyby równocześnie aktywne wewnątrz monitora. Może temu zapobiec na dwa różne sposoby, albo proces A poczeka aż proces B opuści monitor lub czeka na inny warunek, albo proces B poczeka aż proces A opuści monitor lub czeka na inny warunek. Monitory mogą też korzystać z semaforów.
32. Omów podstawowe metody komunikacji międzyprocesowej.
Istnieją dwa systemy komunikacji między procesami. Są to: pamięć dzielona, system komunikatów. Możemy jednocześnie stosować obydwa rodzaje systemów komunikacji. Systemy z pamięcią dzieloną działają na zasadzie współdzielenia zmiennych. Przy ich pomocy odbywa się wymiana informacji między procesami. W systemie tego typu sposób organizacji komunikacji międzyprocesowej zależy od programistów. System operacyjny dostarcza tylko środków do współdzielenia pamięci. Drugim systemem jest system komunikatów. Pozwala on procesom na wymiane komunikatu między nimi. Jego zaletą jest to, że może on być zastosowany w systemach z procesami o rozłącznych przestrzeniach adresów logicznych. Komunikacje pomiędzy procesami można podzielić na bezpośrednią lub pośrednią. Przy komunikacji bezpośredniej, każdy nadający (odbierający) musi jawnie określić odbiorcę (nadawcę). Do zalet tego sposobu komunikacji należą: -łącze jest tworzone automatycznie dla wybranej pary procesów, -łącze dotyczy tylko dwóch procesów, -między dwoma procesami istnieje tylko jedno łącze, -łącze jest dwukierunkowe. Wady: -zmiana idetyfikatora procesu pociąga za sobą zmiany wszystkich pozostałych procesów. Komunikacja pośrednia polega na odbieraniu (nadawaniu) komunikatów po przez skrzynki pocztowe. Proces nadający komunikat umieszcza go w skrzynce, z której komunikat może być pobrany przez inny proces. Zalety: -łącze między procesami istnieje tylko wtedy, gdy dzielą jedną skrzynkę, -łącze może być związane z więcej niż dwoma procesami, -komunikujące się procesy mogą mieć kilka skrzynek. Wady: -jeśli więcej niż dwa procesy dzielą skrzynkę to musimy stosować, albo identyfikatory przesyłek, albo pozwalać tylko jednemu procesowi wykonywać operacje odbierz, -jeśli skrzynka ma określoną pojemność i jest pełna, to nadawca musi czekać dopułki odbiorca nie odbierze komunikatu, -jeśli skrzynka ma określoną pojemność, to po nadaniu wiadomości nadawca nie wie czy odbiorca otrzymał komunikat, należy więc zaimplementować tutaj system potwierdzenia odbioru komunikatów.
Systemy komunikatów stosuje się szczególnie w systemach rozproszonych, w których procesy mogą pracować na różnych maszynach. W środowiskach tych komunikaty są przekazywane przy pomocy specjalnych lini komunikacyjnych. Systemy z pamięcią współdzieloną stosowane są w systemach scentralizowanych, jednakże wystąpienie błędów może spowodować załamanie całego systemu.
33. W jaki sposób realizowana jest komunikacja międzyprocesowa w WINDOWS 3.1? Co to jest DDE? Omów zasadę pracy.
34. Co to jest blokada w systemie operacyjnym? Omów warunki konieczne jej powstania.
W systemie wieloprogramowym procesy rywalizują o ograniczoną liczbę zasobów. Proces zamawia zasoby. W pzrypadku gdy zamówione zasoby są już zajęte przez inne procesy wchodzi on w stan oczekiwania. W ten aposób może dojść do sytuacji w której każdy z procesów będzie oczekiwał na jakieś zasoby przetrzymywane przez inne procesy. Taki stan systemu nazywamy blokadą. Blokada jednak nie jest zjawiskiem pożądanym gdyż procesy uczestniczące w blokadzie nigdy nie zakończą swojej pracy. Przykład: jeśli w systemie istnieją dwa przewijaki taśmy i dwie drukarki i jeden proces przetrzymuje obydwa przewijaki i potrzebuje drukarki, a drugi proces potrzebuje przewijaka natomiast trzyma obydwie drukarki, to jest to stan blokady. Blokada może powstać wtedy gdy system spełnia następujące cztery warunki:
- wzajemne wyłączanie, conajmniej jeden zasób musi być niepodzielny. Tak więc tylko jeden proces może używać tego zasobu. Jeżeli inny proces potrzebuje tego zasobu to jest on opóżniony do czasu zwolnienia zasobu.
- przetrzymywanie i oczekiwanie. Musi istnieć proces który ma przydzielony jeden zasób i jednocześnie oczekuje na przydział drugiego zasobu, przetrzymywanego przez inny proces.
- brak wywłaszczeń. Zasoby nie podlegają wywłaszczeniu, a więc mogą być zwolnione tylko przez proces który je przetrzymuje.
- czekanie cykliczne. Musi istnieć zbiór {P0,..,Pn}czekających procesów, w którym P0 czeka na zasób przetrzymywany przez P1, P1 na P2, Pn na P0.
Żeby zaistniała blokada konieczne jest aby spełnione były wszystkie te cztery warunki na raz.
35. Omów metody zpobiegania blokadom.
Żeby zaistniała blokada konieczne jest aby spełnione były wszystkie cztery warunki na raz, a więc żeby zapobiec blokadzie należy zapewnić niespełnienie przynajmniej jednego z nich.
a). Wzajemne wyłączanie. Pewne zasoby są niepodzielne np. drukarka. Jednakże zasoby dzielone nie wymagają dostępu na zasadzie wzajemnego wykluczania np. pliki udostępnione tylko do czytania, kilka procesów może więc czytać jednocześnie plik. W takim przypadku blokada nie może więc zaistnieć. Jednakże część zasobów z natury jest niepodzielna.
b). Przetrzymywanie i oczekiwanie. Aby warunek ten nigdy nie wystąpił żaden proces zamawiający zasób nie powinien mieć żadnych innych zasobów. Można też stosować warunek, że każdy proces musi dostać wszystkie swoje zasoby zanim rozpocznie działanie. Powoduje to jednak że proces przetrzymuje część zasobów przez cały czas działania mimo, że nie będzie z nich korzystał cały czas. Inną wadą tej metody jest to że proces może nigdy nie uzyskać dostępu do wszystkich potrzebnych mu zasobów, czyli dojdzie do głodzenia procesu.
c). Brak wywłaszczeń. Aby zapobiec spełnienia tego warunku można zastosować następującą metodę: jeśli proces posiadający pewne zasoby zgłasza zapotrzebowanie na inny zasób, który jest przydzielony innemu procesowi, to proces żądający traci wszystkie swoje zasoby. Proces zostaje wznowiony dopiero wtedy gdy jego wszystkie dawne zasoby oraz zamawiany zasób, są wolne. Możemy także postąpić w inny sposób: gdy proces zamawia jakiś zasób i jest on niedostępny, lecz proces przetrzymujący te zasoby czeka na przydzielenie innych to są one odbierane. Gdy proces przetrzymujący nie jest w stanie czekania to proces zamawiający musi czekać na zasoby. Proces może być wznowiony gdy otrzyma nowe zasoby i odzyska zasoby stracone podczas czekania. Metod tych nie można jednak stosować dla zasobów których stanu nie można odtworzyć np. drukarki.
d). Czekanie cykliczne. Jeden ze sposobów uniknięcia czekania cyklicznego jest wymuszenie zamawiania zasobów we wzrastającym porządku ich numeracji. Jest to jednak nie wygodny sposób, ponieważ jeśli trzeba zamówić najpierw zasób o wyższym numerze, a następnie o niższym to konieczne jest zwolnienie pierwszego zasobu i powtórne zamówienie.
36. Scharakteryzuj krótko algorytm bankiera unikania blokady.
Jednym z algorytmów unikania blokady jest algorytm bankiera. Nazywa się on tak, dlatego że można go użyć w systemie bankowym dla zachowania płynności finansowej banku. Jego działanie polega na tym, że każdy proces wchodzący do systemu deklaruje maksymalną liczbę egzemplarzy każdego z potrzebnych mu zasobów. Ilość potrzebnych procesowi zasobów nie może przekroczyć liczby dostępnych w systemie zasobów. Gdy zbór zasobów zostanie zamówiony system musi określić czy ich przydzielenie nie postawi systemów w stanie zagrożonym lub blokady. Jeżeli tak, to proces musi poczekać na zwolnienie wystarczającej liczby zasobów. Algorytm bankiera możemy zastosować jedynie w przypadku kiedy mamy do czynienia z zasobami których posiadamy pewną ilość, np. pamięć. Nie można go zastosować np. w przypadku drukarki.
37. Wymień podstawowe cele zarządzania pamięcią operacyjną.
Pamięć operacyjna odgrywa bardzo ważną rolę w pracy systemu komputerowego, ważne jest więc sprawne gospodarowanie pamięcią. W pamięci są przechowywane dane i programy przetwarzane przez procesor centralny. Pamięć operacyjna jest jedyną pamięcią dostępną dla procesora. Istnieją specjalne programy i części systemów operacyjnych zarządzające obsługą pamięci operacyjnej. Do najważniejszych zadań takich programów należą: -utrzymywanie ewidencji zajętych części pamięci wraz z informacją o właścicielu (blok MCB w DOS-e), -decydowanie które procesy mają być załadowane do wolnych obszarów pamięci, -przydzielanie i zwalnianie obszarów pamięci.
38. Co to jest przestrzeń adresów, przestrzeń pamięci oraz pamięć wirtualna?
Pamięć wirtualna - jest techniką, która umożliwia wykonywanie procesów, które nie są w całości przechowywane w pamięci operacyjnej. Pamięć wirtualna pozwala odseparować pamięć logiczną użytkownika od pamięci fizycznej (tworzona jest abstrakcyjna pamięć główna w postaci wielkiej, jednorodnej tablicy do przechowywania informacji). To odseparowanie umożliwia użytkownikowi posługiwanie się wielką pamięcią wirtualną nawet wtedy, gdy w pamięci fizycznej pozostaje niewiele miejsca.
Przestrzeń pamięci oraz adresów dołączona będzie na kartce z DDE.
39. Omów implemętację pamięci wirtualnej w oparciu o stronicowanie pamięci.
Wstęp o pamięci wirtualnej znajduje się w punkcie 38. Pamięć wirtualna jest najczęściej implementowana w postaci stronicowania na żądanie. W systemie tym procesy przebywają w pamięci pomocniczej (zazwyczaj dysk ). Proces który należy wykonać wprowadzany jest do pamięci. Organizuje się to w ten sposób, że wymieniane są tylko te strony, które są potrzebne. Wymiane stron organizuje na ogół program wymieniana stron (pager). Program wymiany stron unika wczytywania nie używanych stron przez co skraca czas wymiany i zapotrzebowanie na pamięć fizyczną. Program ten używa tzw. tablicy stron, w której jest zapisana min. obecność stron w pamięci. Jeśli proces odwołuje się do stron których nie ma w pamięci to system przerywa proces, pobiera odpowiednią stronę z pamięci pomocniczej i wznawia wykonywanie procesu od przerwanej pozycji. Aby to wykonać sprzęt musi umieć wznowić wykonanie rozkazu po błędzie strony. Może tu jednak wystąpić zjawisko nadprzydziału, zdarza się ono wtedy gdy w pamięci nie ma miejsca na wczytanie potrzebnej strony. Wtedy system przygotowuje się do zastąpienia. Polega to na znalezieniu nie używanej ramki i zwolnieniu jej (zapisanie na dysk). w tym momencie system ma wolną ramkę na wprowadzenie strony. Operacja ta powoduje wydłużenie czasu dostępu do pamięci na skutek podwójnej operacji na dysku (zapis odczyt). Żeby tego uniknąć dodaje się do tablicy stron tzw. bit modyfikacji. Wskazuje on czy strona została zmodyfikowana podczas pobytu w pamięci. Nie modyfikowana strona nie musi być zapisana na dysk. Istnieje kilka algorytmów zastępowania stron. Można tu stosować typowy algorytm obsługi kolejki np. FIFO. Częściej jednak stosuje się specjalnie stworzone do tego celu algorytmy. Jednym z nich jest algorytm optymalny. Posiada on najniższy współczynink błędów strony. Działa on w ten sposób, że wymienia najdłużej nie używaną stronę w pamięci. Innym przykładem algorytmu jest algorytm zastępujący najdawniej używane strony tzw. LRU (Last recently used). Innym problemem związanym z pamięcią wirtualną jest przydział ramek. Stosuje się tu dwa algorytmy przydziału. Pierwszy z nich to tzw algorytm minimalnej liczby ramek. Polega on na przydzielaniu procesowi jak najmniejszej koniecznej do działania procesu liczby ramek. Powoduje to jednak że proces często odwołuje się do stron których nie ma w pamięci. Powoduje to przerwanie wykonywania rozkazu dla pobrania strony, co powoduje wydłużenie czasu pracy w systemie. Inną metodą nazywaną przydziałem równym jest rozdzielenie każdemu z procesów takiej samej ilości ramek. Powoduje on jednak przydzielenie za dużej ilości stron dla małych programów. Z tego powodu częściej stosuje się przydział proporcjonalny. Polega on na przydziale pamięci proporcjonalnej do wielkości procesu.
40. Na czym polega segmentacja pamięci ? Jak wykorzystać ją do implementacji pamięci wirtualnej ?
Segmentacją nazywamy schemat zarządzania pamięcią operacyjną, który urzeczywistnia sposób widzenia pamięci przez użytkownika. Program widziany przez użytkownika można traktować jako zbiór podprogramów, procedur, funkcji lub modułów z wyróżnionym programem głównym. Każdy z tych elementów można traktować jako odrębny segment o zmiennej długości. Elementy wewnątrz takiego segmentu są identyfikowane za pomocą ich odległości od początku segmentu. Użytkownik określa każdy adres za pomocą dwóch wielkości: nazwy segmentu i odległości wewnątrz segmentu. Nazwa segmentu identyfikowana jest za pomocą numerów, które są tworzone w procesie kompilacji. Ponieważ rzeczywista pamięć fizyczna jest jednowymiarowym ciągiem słów więc należy zdefiniować tablicę segmentów, która będzie odwzorowywała dwuwymiarowe adresy określone przez użytkownika na jednowymiarowe adresy fizyczne. Adres logiczny składa się z dwóch części: s-numeru segmentu, d-odległości w tym segmencie. Numer segmentu służy jako indeks do tablicy segmentów. Każda pozycja w tablicy segmentów składa się z bazy segmentu i granicy segmentu. Odległość d adresu logicznego musi zawierać się w przedziale od 0 do granicy segmentu. Jeśli jest ona większa to w systemie operacyjnym generowana jest pułapka (error: adres logiczny poza końcem segmentu). Jeśli mieści się w zadanym przedziale, to jest ona dodawana do bazy segmentu w celu wytworzenia fizycznego adresu potrzebnego słowa. Tablica segmentów jest zatem wykazem par rejestrów bazy i granicy.
Tablica segmentów może być umieszczona w szybkich rejestrach lub w pamięci operacyjnej. Do tablicy segmentów przechowywanych w rejestrach jest szybki dostęp - dodawanie do bazy i porównywanie z wartością graniczną może być wykonywane jednocześnie dla zaoszczędzenia czasu. Gdy program składa się z dużej liczby segmentów to trzymanie tablicy segmentów w rejestrach staje się niemożliwe, więc jest ona przechowywana w pamięci operacyjnej. Rejestr bazowy tablicy segmentów wskazuje na tablicę segmentów. Z powodu zbyt dużej ilości segmentów na jeden program stosuje się również rejestr długości tablicy segmentów. Mając adres logiczny (s,d) sprawdza się najpierw poprawność numeru s segmentu (tzn. czy s jest mniejszy od zawartości rejestru długości tablicy segmentów). Następnie dodaje się numer segmentu do rejestru bazowego tablicy segmentów i otrzymuje adres przechowywania w pamięci odpowiedniej pozycji w tablicy segmentów. Następnie czyta się z pamięci zawartość tej pozycji i sprawdza się, czy odległość nie przekracza długości segmentu, po czym oblicza adres fizyczny danego słowa jako sumę bazy segmentu i odległości. Ponieważ odwzorowanie to wymaga dwu odwołań do pamięci dla każdego adresu logicznego, co spowolnia system komputerowy, stosuje się zbiór rejestrów asocjacyjnych, w których są przechowywane ostatnio używane pozycje tablicy segmentów. Skraca to znacznie czas zużywany na dostęp do pamięci.
Pamięć wirtualna jest techniką, która umożliwia wykonywanie procesów, które nie są w całości przechowywane w pamięci operacyjnej. Pamięć wirtualna pozwala odseparować pamięć logiczną użytkownika od pamięci fizycznej (tworzona jest abstrakcyjna pamięć główna w postaci wielkiej, jednorodnej tablicy do przechowywania informacji). To odseparowanie umożliwia użytkownikowi posługiwanie się wielką pamięcią wirtualną nawet wtedy, gdy w pamięci fizycznej pozostaje niewiele miejsca. Jedną z metod implementacji pamięci wirtualnej jest segmentacja na żądanie. Metoda ta charakteryzuje się tym, że pamięć w systemie przydzielana jest segmentami. Segmenty opisane są za pomocą deskryptorów segmentów, które zawierają informację o długości segmentu, trybie jego ochrony i umiejscowieniu. Wykonywany proces nie musi mieć w pamięci wszystkich swoich segmentów. Deskryptor segmentu zawiera bit poprawności, który pełni funkcję informującą, czy dany segment znajduje się aktualnie w pamięci. Jeśli segment znajduje się w pamięci (bit ustawiony jest na 1) to dostęp następuje bez przestojów, jeśli segmentu nie ma w pamięci (bit ustawiony jest na 0) to wywoływana jest pułapka systemowa. Powoduje to wysłanie innego (nieużywanego) segmentu do pamięci pomocniczej i sprowadzenie wywoływanego segmentu do pamięci operacyjnej. Rozkaz który żądał dostępu do segmentu jest dalej wykonywany. Aby system wiedział, który segment należy usunąć z pamięci, korzysta z bitu udostępnienia znajdującego się w deskryptorze segmentów. Bit ten jest ustawiany wtedy, gdy jakikolwiek bajt segmentu zostanie odczytany lub zapisany. Tworzona jest kolejka z deskryptorów wszystkich segmentów w pamięci. Po każdym kwancie czasu system operacyjny wysuwa na początek kolejki segmenty z ustawionymi bitami udostępnienia, które są następnie zerowane. Tworzy się uporządkowanie, w którym ostatnio używane segmenty są na początku. W przypadku pojawienia się pułapki systemowej (brak segmentu) procedury zarządzania pamięcią określają, czy dostępna wolna pamięć wystarczy na umieszczenie segmentu. Jeśli brak wolnej pamięci (nawet po czynnościach uporządkowania wolnych miejsc w jednym obszarze) to z końca kolejki wybierany jest segment i przesyłany do pamięci pomocniczej, a potrzebny segment (jeśli nowo otrzymany wolny obszar jest wystarczająco duży) przesyłany jest do pamięci i uaktualniany jest jego deskryptor segmentu oraz kolejka deskryptorów. Jeśli nowo powstały wolny obszar nadal jest zbyt mały aby pomieścić nowy segment to cykl opisany wyżej się powtarza.
41. Wymień podstawowe cele zarządzania pamięcią operacyjną.
Podstawowym celem zarządzania pamięcią operacyjną jest jednoczesne utrzymywanie wielu procesów w pamięci operacyjnej dla umożliwienia wieloprogramowości. Poprzez umieszczenie kilku procesów jednocześnie w pamięci i w wyniku planowania przydziału procesora poszczególnym procesom można zwiększyć jego wykorzystanie. Ponadto wykorzystanie strategii przydziału pamięci niesie za sobą wymierne korzyści. Dla przykładu wykorzystanie pamięci wirtualnej, czyli techniki pozwalającej na odwzorowywanie wielkiej logicznej przestrzeni adresowej na mniejszą pamięć fizyczną umożliwia wykonywanie dużych, pamięciożernych procesów pomimo, że nie są one w całości umieszczane w pamięci operacyjnej. A więc można wykonywać programy, które są większe niż pamięć fizyczna Daje to również wiele korzyści. Po pierwsze program przestaje być ograniczany wielkością dostępnej pamięci fizycznej, użytkownicy mogą pisać programy w bardzo dużej wirtualnej przestrzeni adresowej, co upraszcza programowanie, po drugie każdy program użytkownika może zajmować mniejszy obszar pamięci fizycznej, można zatem w tym samym czasie wykonywać więcej programów, uzyskując lepsze wykorzystanie procesora i przepustowość, bez zwiększenia czasu odpowiedzi lub czasu cyklu przetwarzania, po trzecie maleje liczba operacji wejścia-wyjścia koniecznych do załadowania lub wymiany programów użytkowych w pamięci, zatem każdy program użytkownika powinien wykonywać się szybciej. Innym celem zarządzania pamięcią operacyjną jest łatwe kontrolowanie dostępu do danych poprzez ochronę pamięci. W środowisku stronicowym służą do tego bity ochrony, przypisane każdej ramce. Bity te znajdują się zazwyczaj w tablicy stron. Jeden bit może określać stronę jako dostępną do czytania lub pisania lub jedynie do czytania. Aby zapobiec niepożądanemu zapisowi na stronę dostępną jedynie do odczytu generowana jest pułapka systemowa ( próba naruszenia ochrony pamięci ). W środowisku w którym wykorzystywana jest segmentacja bity ochrony pamięci zapisane są w tablicy segmentów. Stosowanie zarządzania pamięcią operacyjną pozwala również na dzielenie kodu lub danych co umożliwia lepsze gospodarowanie pamięcią. Dzielenie wymaga na ogół stosowania segmentacji lub stronicowania, jednak przyczynia się do znacznego podwyższenia poziomu wieloprogramowości.
42. Omów podstawowe strategie przydziału pamięci.
W systemie wieloprogramowym w pamięci operacyjnej przebywa wiele różnych procesów. Procesor jest szybko przełączany od jednego procesu do drugiego. Problem zarządzania pamięcią polega na przydzielaniu pamięci rozmaitym procesom pozostającym w kolejce wejściowej w oczekiwaniu na wprowadzenie do pamięci. Jednym z najprostszych schematów przydziału pamięci jest podzielenie jej na pewną liczbę obszarów o ustalonym rozmiarze. Każdy obszar może zawierać dokładnie jeden proces. Stopień wieloprogramowości jest więc ograniczony przez liczbę obszarów. Kiedy powstaje wolny obszar, następuje wybranie jakiegoś procesu z kolejki wejściowej i wprowadzenie go do tego obszaru Gdy proces kończy działanie, zajmowany przez niego obszar zwalnia się dla innego procesu. System operacyjny przechowuje tablice z informacjami o tym, które części pamięci są dostępne, a które zajęte. Na początku cała pamięć jest dostępna dla procesów użytkowych i jest traktowana jako jeden wielki blok pamięci - dziura. Gdy przybywa proces z zapotrzebowaniem na pamięć, poszukuje się dla niego wystarczająco obszernej dziury. Jeśli zostanie znaleziona, przydziela się z niej pamięć dla procesu tylko w niezbędnej ilości. Na ogół w każdej chwili istnieje zbiór dziur o różnych wymiarach, rozproszonych po całej pamięci. Najbardziej znane strategie przydziału pamięci (wyboru wolnego obszaru ze zbioru dostępnych dziur) to:
1. wybór pierwszej pasującej dziury - w metodzie tej przydziela się pierwszą dziurę o wystarczającej wielkości. Można rozpocząć szukanie od początku wykazu dziur lub od miejsca, w którym zakończono ostanie szukanie. Kończy się z chwilą napotkania dostatecznie dużej wolnej dziury.
2. wybór najlepiej pasującej dziury - przydziela się najmniejszą z dostatecznie dużych dziur. Należy przejrzeć całą listę, chyba, że jest ona uporządkowana według rozmiarów. Ta strategia zapewnia najmniejsze pozostałości po podziale.
3. wybór najgorzej pasującej dziury - przydziela się największą dziurę. Również w tym przypadku należy przeszukać całą listę, chyba, że jest ona uporządkowana według rozmiarów. Strategia taka pozostawia po podziale największą dziurę, która może okazać się bardziej użyteczna niż dziura pozostała w przypadku wyboru strategii przydzielania najlepiej pasującej dziury.
Procesy przybywające do systemu i oczekujące na przydział pamięci są ustawiane w kolejce wejściowej. Przy podejmowaniu decyzji o przydziale pamięci program zarządzający pamięcią bierze pod uwagę zapotrzebowanie na pamięć każdego z procesów oraz ilość dostępnej pamięci. Po uzyskaniu przydziału pamięci proces zostaje do niej załadowany (i przemieszczony, jeśli zachodzi taka potrzeba). Od tej chwili może on rywalizować o przydział procesora. Gdy proces zakończy działanie, wówczas zwalnia pamięć, którą planista zadań może następnie zapełnić innym procesem z kolejki wejściowej. W każdej chwili jest znana lista rozmiarów dostępnych bloków oraz kolejka wejściowa. Program zarządzający pamięcią może porządkować kolejkę wejściową zgodnie z algorytmem planowania. Procesy otrzymują przydziały pamięci aż do chwili, kiedy okaże się, że zapotrzebowanie na pamięć kolejnego procesu nie może być spełnione gdyż żaden dostępny blok pamięci (dziura) nie jest wystarczająco duży, żeby pomieścić proces. Program zarządzania pamięcią może wówczas czekać na pojawienie się dostatecznie dużego bloku lub może przeskoczyć dany proces w kolejce, aby sprawdzić, czy któryś z procesów o niższym priorytecie nie ma odpowiednio mniejszych wymagań pamięciowych. Decyzja taka prowadzi do wyboru między planowaniem z przeskokami i bez.
43. Omów problemy związane z fragmentacją zewnętrzną i wewnętrzną
Istnienie fragmentacji zewnętrznej objawia się tym, że w czasie gdy następuje ładowanie i usuwanie procesów z pamięci i przestrzeń wolnej pamięci dzieli się na małe obszary - suma wszystkich wolnych obszarów w pamięci wystarcza na spełnienie zamówienia (czyli możliwe byłoby przydzielenie żądanej pamięci), ale nie stanowi ona spójnego obszaru. Pamięć jest podzielona na dużą liczbę małych dziur. W zależności od ogólnej ilości miejsca w pamięci i średniej długości procesu, zewnętrzna fragmentacja może być problemem błahym lub poważnym. Istnieje wiele metod zapobiegania, a właściwie zmniejszania wielkości zewnętrznej fragmentacji. Jedną z nich jest upakowanie, czyli takie poprzemieszczanie zawartości pamięci, aby cała wolna pamięć znalazła się w jednym wielkim bloku. Wiąże się to z przemieszczeniem wszystkich wewnętrznych adresów danego procesu. Upakowanie pamięci jednak nie zawsze jest możliwe. Jeśli przemieszczanie jest statyczne i wykonywane podczas tłumaczenia lub ładowania programu to upakowanie nie jest możliwe. Możliwość upakowania daje jedynie dynamiczne przemieszczanie adresów, wykonywane podczas działania programu. Jeśli adresy są przemieszczane dynamicznie, to przemieszczenie procesu sprowadza się do przesunięcia programu i danych oraz do zmiany zawartości rejestru bazowego dla odzwierciedlenia nowego adresu bazowego. Innym sposobem rozwiązania problemu zewnętrznej fragmentacji jest stosowanie stronicowania pamięci. Pozwala ono na to, aby pamięć procesu była nieciągła, a wiec można przydzielać procesowi pamięć fizyczną w tych miejscach, w których nie jest ona zajęta. Stronicowanie polega na podziale pamięci fizycznej na bloki o stałej długości zwane ramkami. Pamięć logiczna jest również podzielona na bloki o takim samym rozmiarze zwane stronami. Gdy ma nastąpić wykonanie procesu, wówczas jego strony, przebywające w pamięci pomocniczej są wprowadzane w dowolne ramki. Korzystanie ze stronicowania eliminuje wprawdzie fragmentację zewnętrzną, lecz może wystąpić fragmentacja wewnętrzna.
Fragmentacja wewnętrzna ma miejsce wtedy, gdy procesowi przydzielona zostanie nieco większa pamięć niż ta, której zażądał. Wówczas powstaje efekt pozostawienia niewykorzystanego fragmentu pamięci wewnątrz przydzielonego obszaru. W stronicowym zarządzaniu pamięcią operacyjną fragmentacja wewnętrzna wystąpi wtedy, gdy wymagania pamięciowe procesu nie odpowiadają dokładnie wielokrotności rozmiaru ramek. Ostania przydzielona ramka zawsze wtedy nie będzie wykorzystywana w stu procentach. Fragmentację wewnętrzną można eliminować stosując segmentację pamięci ( jednostki przydziału pamięci są zmiennej długości ).
44. Jakie znasz strategie pobierania z pamięci pomocniczej?
Istnieje wiele strategii pobierania z pamięci pomocniczej. W zależności od metody przydziału miejsca na dysku stosuje się różne algorytmy pobierania danych z pamięci pomocniczej. I tak w metodzie przydziału ciągłego, w której każdy plik musi zajmować ciąg kolejnych adresów na dysku i adresy dyskowe definiują na dysku uporządkowanie liniowe dostęp do pliku jest dosyć łatwy. System plików pamięta adres dyskowy ostatniego bloku, do którego było odniesienie i w razie potrzeby czyta następny blok (plik traktujemy jako ciąg bloków). Jest to dostęp sekwencyjny. W celu bezpośredniego dostępu do bloku i w pliku zaczynającym się od bloku b można odnieść się wprost do bloku b+i. Tak więc w metodzie przydziału ciągłego można implementować zarówno dostęp sekwencyjny, jak i swobodny. W innej metodzie - przydziału listowego każdy plik stanowi listę powiązanych ze sobą bloków dyskowych, bloki te mogą znajdować się gdziekolwiek na dysku. Katalog dysku zawiera wskaźnik do pierwszego i ostatniego bloku pliku. Każdy blok zawiera wskaźnik do następnego bloku. Wskaźniki te nie SA dostępne dla użytkownika. Czytanie pliku, a wiec pobieranie z pamięci pomocniczej polega na odczytaniu pierwszego bloku, wskaźnik do tego bloku zapisany jest w katalogu urządzenia, a następnie korzystając z właściwości, że każdy blok posiada wskaźnik do następnego bloku, odczytuje się kolejne bloki należące do pliku. Dostęp ten jest niestety sekwencyjny, co ogranicza w znacznym stopniu zastosowanie. Pewną odmianą tej metody jest metoda wykorzystująca tablicę przydziału plików. Na dysku wydziela się sekcję, która zawiera tablicę. Tablica ta ma po jednej pozycji dla każdego bloku dyskowego i jest indeksowana za pomocą numerów bloków. Tablicy tej używa się podobnie jak listy powiązań. Katalog zawiera numer pierwszego bloku pliku. Pozycja w tablicy indeksowana przez numer tego bloku zawiera numer następnego bloku w pliku. Łańcuch taki ciągnie się aż do ostatniego bloku, który ma na odpowiadającej mu pozycji w tablicy specjalny symbol końca pliku. Bloki nieużywane są wskazywane za pomocą liczby 0 umieszczonej na ich pozycji w tablicy. Ponieważ metoda przydziału listowego nie może służyć do organizacji dostępu bezpośredniego więc wykorzystuje się przydział indeksowy, który charakteryzuje się tym, iż każdy plik ma własny blok indeksowy, będący tablicą adresów bloków dyskowych. Pozycja o numerze i w bloku indeksowym wskazuje na blok i danego pliku. Katalog zawiera adres bloku indeksowego. Aby przeczytać blok i używa się wskaźnika z pozycji o numerze i w bloku indeksowym, za pomocą którego znajduje się odpowiedni blok do czytania. Dostęp do plik może być bezpośredni. W niektórych systemach przydział indeksowy łączy się z przydziałem ciągłym w ten sposób, że do małych plików (złożonych zaledwie z kilku bloków) stosuje się przydział ciągły i automatycznie przechodzi na przydział indeksowy, jeśli plik przybiera większy rozmiar.
45. Omów mechanizmy procesora INTEL 80386 i wyżej do zarządzania pamięcią wirtualną.
Procesor INTEL 80286 nie ma możliwości stronicowania, ale operuje segmentami, dlatego pracujące na tym procesorze systemy operacyjne (np. OS/2) wykorzystują zawarte w sprzęcie możliwości segmentacji do implementacji pamięci wirtualnej (segmentacja na żądanie).
Metoda ta charakteryzuje się tym, że pamięć w systemie przydzielana jest segmentami. Segmenty opisane są za pomocą deskryptorów segmentów, które zawierają informację o długości segmentu, trybie jego ochrony i umiejscowieniu. Wykonywany proces nie musi mieć w pamięci wszystkich swoich segmentów. Deskryptor segmentu zawiera bit poprawności, który pełni funkcję informującą, czy dany segment znajduje się aktualnie w pamięci. Jeśli segment znajduje się w pamięci (bit ustawiony jest na 1) to dostęp następuje bez przestojów, jeśli segmentu nie ma w pamięci (bit ustawiony jest na 0) to wywoływana jest pułapka systemowa. Powoduje to wysłanie innego (nieużywanego) segmentu do pamięci pomocniczej i sprowadzenie wywoływanego segmentu do pamięci operacyjnej. Rozkaz który żądał dostępu do segmentu jest dalej wykonywany. Aby system wiedział, który segment należy usunąć z pamięci, korzysta z bitu udostępnienia znajdującego się w deskryptorze segmentów. Bit ten jest ustawiany wtedy, gdy jakikolwiek bajt segmentu zostanie odczytany lub zapisany. Tworzona jest kolejka z deskryptorów wszystkich segmentów w pamięci. Po każdym kwancie czasu system operacyjny wysuwa na początek kolejki segmenty z ustawionymi bitami udostępnienia, które są następnie zerowane. Tworzy się uporządkowanie, w którym ostatnio używane segmenty są na początku. W przypadku pojawienia się pułapki systemowej (brak segmentu) procedury zarządzania pamięcią określają, czy dostępna wolna pamięć wystarczy na umieszczenie segmentu. Jeśli brak wolnej pamięci (nawet po czynnościach uporządkowania wolnych miejsc w jednym obszarze) to z końca kolejki wybierany jest segment i przesyłany do pamięci pomocniczej, a potrzebny segment (jeśli nowo otrzymany wolny obszar jest wystarczająco duży) przesyłany jest do pamięci i uaktualniany jest jego deskryptor segmentu oraz kolejka deskryptorów. Jeśli nowo powstały wolny obszar nadal jest zbyt mały aby pomieścić nowy segment to cykl opisany wyżej się powtarza.
46. Opisz model zbioru roboczego w zarządzaniu pamięcią operacyjną. Co to jest szamotanie?
Gdy liczba ramek przydzielonych do niskopriorytetowego procesu spada poniżej minimum wymaganego przez architekturę komputera, wówczas wykonanie takiego procesu musi zostać zawieszone. Należy usunąć pozostałe strony procesu, zwalniając wszystkie ramki, które były mu przydzielone. odpowiadają za to procedury wymiany (wprowadzanie i wyprowadzanie) ze średniego poziomu planowania przydziału procesora. Popatrzmy na proces który nie ma „dość” ramek. Zawsze będzie istniała pewna (większa) liczba stron aktywnie używanych. Jeśli proces nie będzie miał takiej liczby ramek, to szybko wystąpi brak strony. Wtedy któraś ze stron będzie musiała byc zastąpiona. Ponieważ wszystkie strony są aktywnie używane, więc trzeba będzie zastąpić jakąś stronę, która za chwilę okaże się potrzebna. W konsekwencji, w procesie bardzo szybko będą następować po sobie kolejne błędy braku strony. Proces będzie ciągle wykazywał brak strony, wymieniając jakąś stronę, po czym - z powodu jej brzku - sprowadzając ją z powrotem. Taką bardzo dużą aktywność stronicowania określa się terminem szamotania. Proces szamoce się jeśli spędza więcej czasu na stronicowaniu niż na wykonaniu.
47. Co to jest plik, jakie ma właściwości i jakie podstawowe operacje są wykonywane na plikach?
Plik - jest to zbiór powiązanych ze sobą informacji określonych przez jego twórcę. Najczęściej pliki reprezentują programy oraz dane. Pliki danych mogą być liczbowe, literowe, alfanumeryczne lub dwójkowe. Pliki mogą mieć format swobodny, jak np. pliki tekstowe lub ściśle określony. Ogólnie plik jest ciągiem bitów, bajtów, wierszy lub rekordów, których znaczenie określa twórca pliku i jego użytkownik.
Każdy plik ma nazwę za pomocą której można się do niego odwoływać, typ, czas założenia, nazwę (lub numer rachunku) jego twórcy, długość, itp. Plik ma określoną strukturę, stosownie do swojego typu. Plik tekstowy jest ciągiem znaków składających się na wiersze/strony; plik źródłowy jest ciągiem podprogramów i funkcji, które mają własną organizację np. deklaracje poprzedzają wykonywalne funkcje; plik wynikowy jest ciągiem bajtów połączonych w bloki odpowiednio interpretowane. Ważne jest tu szczególnie określenie typu pliku (np. plik tekstowy, dBase, itp.) aby system operacyjny wiedział co może z danym plikiem zrobić. W zależności od rodzaju systemu op. W katalogach umieszcza się różne informacje o plikach : nazwa, typ pliku (potrzebne w systemach w których rozróżnia się typy plików), lokalizacja (jest to wskaźnik do urządzenia i lokalizacja pliku na tym urządzeniu), rozmiar, bieżące położenie (jest to wskaźnik do bieżącej pozycji czytania lub pisania w pliku), ochrona (do sprawdzania kto może czytać lub pisać w pliku), licznik użycia (informacja o liczbie procesów używających jednocześnie dany plik), czas, data i identyfikator procesu (mogą być przechowywane ze względu na tworzenie, ostatnio wprowadzone zmiany i ostatnie użycie pliku).
Operacje wykonywane na plikach:
- tworzenie pliku Niezbędne jest tu znalezienie miejsca na plik i utworzenie w katalogu pozycji nowego pliku.
- pisanie pliku Aby pisać w pliku, wywołuje się funkcję systemową podając nazwę pliku i informację która ma być w pliku zapisana. System wtedy przeszukuje katalog, w celu znalezienia lokalizacji pliku. W katalogu zazwyczaj znajduje się wskaźnik do bieżącego pliku. Przy użyciu tego wskaźnika można obliczyć adres następnego bloku i zapisać informację. Wskaźnik ten musi być uaktualniany.
- czytanie pliku j. w. tylko że dla czytania a nie pisania
- ustawianie pliku w stan początkowy; Katalog przeszukuje się w celu odnalezienia odpowiedniej pozycji, po czym wskaźnik bieżącej pozycji w pliku ustawia się na początek pliku.
- usuwanie pliku; Aby usunąć plik odnajduje się jego nazwę w katalogu. po odnalezieniu tej nazwy zwalnia się całą przestrzeń zajmowaną przez plik (aby mogły jej używać inne pliki) i likwiduje się daną pozycję w katalogu.
48. Omów zasady współużytkowania i ochrony informacji w systemie operacyjnym.
Ochrona - mechanizm służący do kontrolowania dostępu programów, procesów lub użytkowników do zasobów zdefiniowanych przez system komputerowy.
Bezpieczeństwo jest miarą zaufania, że będzie zachowana nienaruszalność systemu i jego danych.
Rolą ochrony w systemie komputerowym jest dostarczenie mechanizmu do wymuszania polityki rządzącej sposobem użycia zasobu.
MACIERZ DOSTĘPÓW. System komputerowy jest zbiorem procesów i obiektów (są to el. sprzętowe(drukarki, dyski,...) i el. programowe (pliki, programy,...)).Proces powinien mieć dostęp tylko do tych zasobów, do których został uprawniony i w każdej chwili powinien mieć możliwość kontaktu tylko z tymi zasobami których aktualnie potrzebuje do zakończenia zadania (zasada wiedzy koniecznej ang. need-to-know). Aby wygodniej posługiwać się tym schematem, wprowadza się pojęcie domeny ochrony. proces działa wewnątrz domeny, która określa dostępne dla niego zasoby. Każda domena definiuje zbiór obiektów i rodzaje operacji, które można wykonywać dla danego obiektu. Możliwość wykonywania operacji na obiekcie stanowi prawo dostępu.
Nasz model ochrony można rozważyć abstrakcyjnie jako macierz zwaną macierzą dostępów. Wiersze tej macierzy reprezentują domeny, a kolumny obiekty. Każdy element macierzy zawiera zbiór praw dostępu. Ponieważ obiekty są zdefiniowane jawnie za pomocą nazw kolumn, można pominąć nazwę obiektu w prawie dostępu. Element dostęp określa zbiór operacji, które proces działający w domenie może wykonać na obiekcie.
TABLICA GLOBALNA jest najprostszą metodą realizacji macierzy dostępów. Składa się ona ze zbioru trójek uporządkowanych. Za każdym razem gdy operacja M ma być wykonana na obiekcie O w domenie D szuka się trójki <D, O, R>, M∈R. Jeśli trójka taka zostanie odnaleziona to operację nożna wykonać. Wada : ogrom tablicy, jeśli jakiś obiekt jest dostępny dla wszystkich do czytania, to musi on występować osobno w każdej domenie.
WYKAZY DOSTĘPÓW. Można utworzyć wykaz dostępów do każdego z obiektów złożony z par uporządkowanych <domena, zbiór praw>, które definiują wszystkie domeny z niepustymi zbiorami praw dostępu do danego obiektu. Podejście to można rozszerzyć dodając do zdefiniowanego wykazu standardowe zbiory praw dostępu. Kiedy pojawi się próba wykonania operacji M na obiekcie O w domenie D wtedy w wykazie dostępów szuka się obiektu O i związanej z nim pozycji <D, R> M∈R. Jeśli taka pozycja zostanie odnaleziona, to udziela się zezwolenia na wykonanie operacji. Gdy nie ma odpowiedniej pozycji w wykazie, wówczas przeszukuje się standardowy zbiór praw dostępu. Jeśli operacja M. znajduje się w tym zbiorze to zezwala się na dostęp. Przeszukiwanie będzie skuteczniejsze gdy najpierw przeszukiwany będzie standardowy zbiór praw dostępu, a później wykaz dostępów.
WYKAZY MOŻLIWOŚCI. Zamiast kojarzyć kolumny macierzy dostępów z obiektami - jako wykazy dostępów można każdy wiersz tej macierzy powiązać z jego domeną. Wykaz możliwości domeny jest listą obiektów i operacji które można wykonywać na tych obiektach. Obiekt jest często reprezentowany przez jego nazwę fizyczną lub adres - zwane możliwością. W celu wykonania operacji M na obiekcie O proces wykonuje operację M., jako parametr określając możliwość dostępu do obiektu O. Aby uzyskać dostęp do obiektu, wystarcza mieć możliwość. Wykaz możliwości jest związany z domeną, lecz nigdy nie jest dostępny bezpośrednio dla procesu działającego w tej domenie. W zamian sam wykaz możliwości jest obiektem chronionym, utrzymywanym przez system operacyjny i dostępnym dla użytkownika tylko pośrednio. Ochrona sprawowana na podstawie możliwości polega na fakcie, że możliwości nie mogą nigdy przedostać się do obszaru pamięci dostępnego bezpośrednio dla procesu użytkownika.
MECHANIZM ZAMKA Z KLUCZEM. (Każdy obiekt ma wykaz jednoznacznych wzorców bitowych, zwanych zamkami, a każda domena ma wykaz jednoznacznych wzorców bitowych, zwanych kluczami. Proces działający w domenie może mieć dostęp do obiektu tylko wtedy, gdy dana domena ma klucz pasujący do jednego z zamków tego obiektu.)
PORÓWNANIE. Gdy użytkownik tworzy obiekt może wówczas określić które domeny mają mieć dostęp do tego obiektu i za pomocą jakich operacji. Z uwagi na to, że informacja o prawach dostępu w poszczególnych domenach nie jest zlokalizowana, trudno określać zbiór praw dla każdej domeny. Ponadto każdy dostęp do obiektu musi podlegać sprawdzaniu, co wymaga przeszukiwania wykazu dostępów. W dużych systemach z długimi wykazami dostępów przeszukiwanie może być czasochłonne). Proces usiłujący uzyskać dostęp do obiektu musi wykazać, że ma taką możliwość. Zatem system ochrony musi tylko sprawdzić czy ta możliwość jest prawomocna.
POLITYKA. Macierz dostępów dostarcza mechanizmu, który pozwala podejmować różne decyzje polityczne. Mechanizm ten polega na implementowaniu macierzy dostępów i gwarantowaniu, że określone właściwości semantyczne muszą być zagwarantowane. mówiąc dokładniej musi być zagwarantowane, że proces działający w domenie D może mieć dostęp tylko do obiektów wyspecyfikowanych w wierszu i, przy tym tylko w sposób określony poprzez odpowiednie elementy macierzy dostępów. Za pomocą macierzy dostępów można realizować decyzje polityczne dotyczące dostępów. Decyzje te dotyczą praw, które powinny znaleźć się w elementach (i,j) tej macierzy. Należy również określić domenę działania każdego procesu. Użytkownicy na ogół decydują o zawartości elementów macierzy dostępów. Gdy użytkownik tworzy nowy obiekt O, wówczas do macierzy dostępów jest dodawana kolumna O złożona z odpowiednio zainicjowanych elementów określonych wedle życzenia twórcy obiektu. Stosownie do potrzeb użytkownik może decydować o wprowadzeniu w kolumnie j pewnych praw w jednych elementach oraz innych praw w innych elementach.
DYNAMICZNE STRUKTURY OCHRONY. Związek między domeną może być statyczny (jeśli zbiór zasobów dostępnych dla procesu jest ustalony podczas dalszego działania) lub dynamiczny. Jeśli związek między procesem a domeną jest ustalony i chcielibyśmy dołączyć do niego zasadę „wiedzy koniecznej”, to okaże się niezbędny mechanizm zmiany zawartości domeny. Wykonanie jakiegoś procesu można podzielić na 2 różne fazy. Np. proces może potrzebować możliwości czytania w jednej fazie i pisania w drugiej. Jeśli macierz dostępów jest statyczna to należy zdefiniować domenę zawierającą prawa dostępu zarówno do czytania, jak i do pisania. Takie rozwiązanie zawiera więcej praw niż jest wymaganych w każdej z dwóch faz, ponieważ proces otrzymuje dostęp do czytania w fazie, w której wystarczyłby mu dostęp do pisania i na odwrót. Zatem zasada „wiedzy koniecznej” jest naruszona. Należy pozwolić na dokonywanie zmian w zawartości macierzy dostępów, tak aby mogła ona zawsze odzwierciedlać minimum. Jeśli związek między procesem a domeną jest dynamiczny, to uzyskuje się mechanizm pozwalający procesowi na przełączanie się od jednej domeny do drugiej. Może być również pożądana zmiana zawartości domeny. Jeśli nie można zmienić zawartości domeny to ten sam efekt można uzyskać przez utworzenie nowej domeny ze zmienioną wartością i przełączenie się do tej domeny wówczas, gdy staje się konieczna zmiana zawartości domeny.
UNIEWAŻNIANIE PRAW DOSTĘPU. W systemie ochrony dynamicznej może być czasami niezbędne unieważnienie praw dostępu do obiektów dzielonych przez różnych użytkowników Jeśli zastosuje się schemat wykazu dostępów, to unieważnienie będzie całkiem proste. Wyszukuje się w wykazie dostępów prawo (lub prawa) do unieważnienia i usuwa je z wykazu. Unieważnienie jest natychmiastowe i może być ogólne lub wybiórcze (cofnięcie prawa dotyczy wszystkich użytkowników czy tylko danej grupy użytkowników), całkowite lub częściowe (czy unieważnić wszystkie prawa związane z obiektem czy tylko ich część), stałe lub czasowe (jeśli stałe to nigdy już nie będzie można osiągnąć danego prawa dostępu). Natomiast w przypadku korzystania z wykazów możliwości, zadanie unieważnienia jest o wiele trudniejsze. Ponieważ możliwości są rozproszone po całym systemie, należy je wpierw odnaleźć. Jest kilka schematów realizacji unieważnienia możliwości :
- Wtórne pozyskiwanie; Możliwości są okresowo usuwane z każdej domeny. Jeśli proces potrzebuje danej możliwości, to wykrywa jej usunięcie i może wtedy spróbować pozyskiwać ją na nowo. Jeśli możliwość została unieważniona, to proces nie będzie mógł uzyskać jej ponownie.
- Wskaźniki zwrotne; Z każdym obiektem jest utrzymywana lista wskaźników do wszystkich związanych z nim możliwości Gdy jest wymagane unieważnienie, można wówczas posługując się tymi wskaźnikami zmieniać możliwości stosownie do potrzeb.
- Sposób pośredni; Możliwości nie wskazują na obiekty wprost, lecz pośrednio. Każda możliwość wskazuje na jednoznaczny element tablicy globalnej, który z kolei wskazuje na obiekt. W celu unieważnienia możliwości przeszukuje się tablicę globalną i usuwa odpowiedni element. Gdy pojawia się próba dostępu wtedy możliwość wskazuje na niedozwolony element. Można bez kłopotu używać powtórnie elementy tej tablicy dla innych możliwości, ponieważ zarówno możliwości, jak i elementy tablicy wskazują na jednoznaczne nazwy obiektu. Obiekt wskazywany przez możliwość oraz odpowiadający mu element tablicy muszą do siebie pasować. Metoda ta nie pozwala na wybiórcze unieważnienia.
- Klucze; Klucz jest jednoznacznym wzorcem bitowym, który można powiązać z każdą możliwością. Klucz taki jest definiowany przy tworzeniu możliwości, przy czym proces mający daną możliwość nie może klucza sprawdzić ani zmienić. Klucz główny związany z każdym obiektem, może być zdefiniowany lub zastąpiony za pomocą operacji ustal klucz(set-key). Bieżącą wartość klucza głównego przyporządkowuje się możliwości przy jej tworzeniu. Podczas sprawdzania możliwości porównuje się jej klucz z kluczem głównym. Jeśli klucze pasują do siebie, to zezwala się na wykonanie operacji. Unieważnienie polega na zastąpieniu klucza głównego nowym wzorcem bitowym za pomocą operacji ustal klucz; delegalizuje to wszystkie dotychczasowe możliwości odnośne do danego obiektu. Ta metoda nie pozwala na selektywne unieważnianie, gdyż każdemu obiektowi przyporządkowany jest tylko jeden klucz główny
49. Na czym polega organizacja pamięci pomocniczej? Wymień jej podstawowe formy.
W większości systemów komputerowych istnieje pamięć pomocnicza jako rozszerzenie pamięci podstawowej (pamięci głównej, pamięci operacyjnej).
Podstawowym zadaniem systemu komputerowego jest wykonywanie programów. Najlepiej by było, gdyby program i dane znajdowałyby się na stałe w pamięci głównej. Nie jest to możliwe bo: 1. pamięć główna jest zwykle za mała by pomieścić wszystkie programy i dane 2. Pamięć główna jest ulotna i po wyłączeniu prądu traci swoją zawartość. Od pamięci pomocniczej (secondary storage, pamięci masowej) wymaga się przede wszystkim, aby można było w niej trwale przechowywać olbrzymie ilości danych. Jednym z pierwszych nośników była taśma magnetyczna. Jest ona bardzo powolna w stosunku do pamięci głównej. Dostęp do danych może być wyłącznie sekwencyjny. Toteż ten typ pamięci jest zupełnie nieprzydatny do organizacji dostępu swobodnego, niezbędnego w pamięci wirtualnej. Obecnie taśm używa się głownie do składowania i przechowywania rzadko używanych danych oraz jako środka przenoszenia informacji z jednego systemu do drugiego. We współczesnych systemach komputerowych rolę masowej pamięci pomocniczej spełniają dyski (głównie magnetyczne, rzadziej optyczne). Teraz trochę o budowie dysków. Kiedy dysk pracuje, wtedy napędzający go silnik wprawia go w ruch wirowy o dużej prędkości (np. 60 obrotów/s). Tuż nad powierzchnią dysku znajduje się głowica czytająco-pisząca. Powierzchnia dysku jest podzielona logicznie na ścieżki. Zapamiętywanie informacji polega na magnetycznym jej zapisywaniu na ścieżce przez głowicę czytająco-piszącą. Dysk o nieruchomych głowicach ma oddzielną głowicę dla każdej ścieżki. Rozwiązanie takie pozwala aby komputer szybko przełączał się ze ścieżki na ścieżkę, ale wymaga użyciawielkiej liczby głowic, czyniąc urządzenie bardzo drogim. Do urządzeń tego typu możemy zaliczyć dyski twarde, dyskietki (dyski elastyczne), itp.
Odniesienia do informacji na dysq mają postać wieloczęściowego adresu, który zawiera numer napędu, powierzchni i ścieżki. Wszystkie ścieżki na jednym napędzie do których możliwy jest dostęp bez przesuwania głowic (są to z zasady ścieżki na różnych powierzchniach) są nazywane cylindrem. W obrębie ścieżki informacja jest zapisana blokami. Bloki te mogą mieć stałe rozmiary, określone przez sprzęt. Nazywa się je sektorami. Każdy sektor może być czytany i zapisywany niezależnie. Istnieje również możliwość przechowywania informacji na ścieżce w blokach o zmiennych długościach pooddzielanych przerwami międzyblokowymi. W wielu systemach stosuje się programowo stałe długości bloków. W każdym przypadku informacja jest czytana i zapisywana blokami. Blokowanie lub rozblokowywanie rekordów wykonywane środkami oprogramowania łatwo ukrywa stałą lub zmienną naturę rozmiaru bloku fizycznego. Sektor jest najmniejszą jednostką informacji, która może być czytana z dysku lub na nim zapisana. Zależnie od napędu dysku, sektory mogą mieć od 32 do 4096 bajtów; na ścieżce umieszcza się 4-32 sektorów, a powierzchnia dysku może zawierać 20-1500 ścieżek. Aby dotrzeć do sektora należy określić powierzchnię, ścieżkę i sektor. W celu dopomożenia sobie w odnalezieniu położenia sektora, napęd zapisuje znaczniki sektorów (sector marks) między sektorami. Głowice czytająco-piszące są przesuwane na właściwą ścieżkę (czas przeszukiwania - seek time) i elektronicznie przełączane na właściwą powierzchnię; później następuje oczekiwanie (czas oczekiwania - latency time) na przejście potrzebnego sektora pod głowicami. Czas przeszukiwania zależy od czasu, który głowice dysku potrzebują na przemieszczenie się, zatem im większa odległość między ścieżkami, tym czas przeszukiwania jest dłuższy. Przesyłanie danych między pamięcią operacyjną a dyskiem odbywa się pojedynczymi sektorami lub porcjami sektorów. Adresowanie poszczególnych sektorów wymaga podania numeru ścieżki (lub cylindra), numeru powierzchni i numeru sektora. Zatem dysk można traktować jako 3-wymiarową tablicę sektorów. Najczęściej system op. traktuje dysk jako 1-wymiarową tablicę bloków dyskowych. Każdy blok stanowi osobny sektor. Na ogół adresy bloków wzrastają wzdłuż wszystkich sektorów na ścieżce, następnie wzdłuż wszystkich ścieżek w cylindrze, a na koniec od cylindra 0 do ostatniego cylindra na dysku. Oznaczymy przez s liczbę sektorów na ścieżce oraz przez t liczbę ścieżek w cylindrze; wtedy przejście od adresu dyskowego sektora k sektora na powierzchni j w cylindrze i do jednowymiarowego numeru bloku b dokonuje się za pomocą wzoru : b=k+s*(j+i*t). Zauważmy, że przy tym odwzorowaniu dostęp do bloku b+1 po bloku b wymaga przeszukiwania tylko wówczas, gdy b był ostatnim blokiem w jednym cylindrze oraz b+1 jest pierwszym blokiem w następnym cylindrze. Nawet wtedy głowica przemieszcza się o jedną ścieżkę. Dyski charakteryzują się 2 ważnymi cechami, które czynią z nich wygodny środek przechowywania licznych plików : 1.Informacje mogą być uaktualniane bez zmiany miejsca; można przeczytać blok z dysku, wprowadzić do niego zmiany i zapisać go z powrotem na tym samym miejscu na dysku 2. Dowolny blok informacji na dysku można zaadresować bezpośrednio. Zatem zarówno sekwencyjny, jak i swobodny dostęp do dowolnego pliku jest łatwy do osiągnięcia, a przełączanie od jednego pliku do drugiego wymaga tylko przesunięcia głowic czytająco-piszących i zaczekania na obrót dysku.
KATALOG URZĄDZENIA. Na dysku z reguły znajduje się katalog urządzenia dyskowego informujący o przechowywanych na nim plikach. Katalog zawiera wykaz nazw plików oraz informacje o rozmieszczeniu pliku na dysku, długości pliku, jego typie, właścicielu, czasie utworzenia, itd. Ponieważ zapisów do bloków dyskowych można dokonywać bez korzystania z dodatkowego miejsca, katalog można wedle potrzeby czytać, uaktualniać i zapisywać ponownie bez konieczności kopiowania reszty dysku. Każda fizyczna jednostka dyskowa - pakiet dysków lub dyskietka - ma własny katalog urządzenia. Katalog urządzenia jest przechowywany na danym urządzeniu, często pod pewnym stałym adresem, takim jak adres dyskowy 00001. (Adres 00000 na ogół jest przeznaczony dla procedury ładującej system). Organizacja ta jest szczególnie przydatna w przypadku wymiennych nośników informacji.
50. Omów poznane metody dostępu do pliku.
DOSTĘP SEKWENCYJNY. Zawartość pliku jest przetwarzana po kolei, jeden rekord za drugim. Jest to pewnie najpowszechniejszy tryb dostępu do pliku. Na przykład edytory komputerowe często używają plików w ten sposób. Większość operacji wykonywanych na plikach to czytania i pisanie. Operacja czytania czyta następną porcję pliku i automatycznie przesuwa wskaźnik pozycji w pliku do przodu. Podobnie operacja pisania umieszcza dane na końcu pliku i ustawia wskaźnik za nowo zapisanymi danymi (nowy koniec pliku). Wskaźnik do pozycji w pliku można ustawić na początku pliku, po czym - w niektórych systemach - program może przeskakiwać w przód lub w tył o n rekordów, dla pewnej wielkości n. Dostęp sekwencyjny jest oparty na taśmowym modelu pliku.
DOSTĘP BEZPOŚREDNI jest przeciwieństwem dostępu sekwencyjnego. Jest on oparty na dyskowym modelu pliku. W dostępie bezpośrednim plik traktuje się jak ciąg ponumerowanych bloków lub rekordów. Plik o dostępie bezpośrednim (swobodnym) pozwala na czytanie/zapisywanie dowolnych bloków. Operacje na plikach muszą być tak zmodyfikowane, aby zawierały jako parametr numer bloku. Numer bloku jest przekazywany przez użytkownika do systemu operacyjnego jest zazwyczaj numerem względnym bloku. Numer względny bloku jest indeksem względem początku pliku. Zatem pierwszy względny blok w pliku ma numer 0, następny 1, itd., nawet jeśli faktyczny, dyskowy adres bezwzględny danego bloku wynosi 14703 dla pierwszego bloku i 3192 dla drugiego. Użycie numerów względnych pozwala systemowi operacyjnemu decydować o tym, gdzie umiejscowić plik i zapobiega sięganiu przez użytkownika do fragmentów systemu plików nie będących częścią jego pliku. Numery względne plików zaczynają się od 0 lub 1 (zależy od systemu).
INNE METODY DOSTĘPU. Te metody z reguły zawierają konstrukcję indeksu pliku. Indeks ten podobnie jak skorowidz na końcu książki zawiera wskaźniki do różnych bloków. Aby znaleźć jakąś pozycję w pliku, przeszukuje się najpierw indeks, a następnie używa wskaźnika w celu uzyskania bezpośredniego dostępu do pliku i odnalezienia pozycji.
51. Omów poznane metody przydziału miejsca na dysku.
PRZYDZIAŁ CIĄGŁY. W tej metodzie każdy plik musi zajmować ciąg kolejnych adresów na dysku. Adresy dyskowe definiują na dysku uporządkowanie liniowe. Zauważmy, że w tym uporządkowaniu dostęp do bloku b+1 po bloku b nie wymaga na ogół ruchu głowicy. Gdy ruch głowicy będzie konieczny (między ostatnim sektorem na jednym cylindrze a pierwszym sektorem na następnym cylindrze), wówczas będzie to przesunięcie tylko o jedną ścieżkę. Tak więc liczba operacji przeszukiwania dysku wymaganych przy rozmieszczeniu plików na dysku metodą ciągłą jest minimalna; dotyczy to także czasu przeszukiwania, jeśli jest ono nieuniknione. Jeśli plik o długości n zaczyna się od adresu bloku b, to zajmować on będzie przy takim przydziale bloki b,b+1,b+2,...,b+n-1. Wadą tego przydziału jest znalezienie miejsca na nowy plik, lub to że trzeba od razu znać wielkość pliku gdyż nie wiadomo jak wielka jest „dziura” w którą dany plik zapisujemy.
PRZYDZIAŁ LISTOWY. Każdy plik stanowi listę powiązanych ze sobą bloków dyskowych; bloki mogą znajdować się gdziekolwiek na dysku. Katalog zawiera wskaźnik do pierwszego i ostatniego bloku pliku. Każdy blok zawiera wskaźnik do następnego bloku. Wskaźniki te nie są dostępne dla użytkownika. Przy tworzeniu pliku tworzy się po prostu nową pozycję w katalogu urządzenia. W przydziale listowym każda pozycja w katalogu ma wskaźnik do pierwszego bloku pliku. Początkową wartością tego wskaźnika jest nil (wartość wskazująca koniec listy) w celu zaznaczenia, że plik jest pusty. Pole rozmiaru również przyjmuje wartość 0. Operacja pisania do pliku usuwa pierwszy wolny blok z listy wolnych obszarów i wypełnia go zapisywaną informacją. Ów nowy blok zostanie następnie dowiązany do końca pliku. Czytanie pliku odbywa się po prostu według wskaźników zapamiętanych w blokach. W tym sposobie nie trzeba znać wielkości pliku w chwili tworzenia, ponieważ jego części są ze sobą powiązane. Wada : nie można stosować tego przydziału wraz z dostępem sekwencyjnym; przestrzeń zajmowana przez wskaźnik. Aby znaleźć dany blok pliku, należy zacząć od początku pliku i postępować za wskaźnikami aż do dotarcia do poszukiwanego bloku pliku. Każdy dostęp do wskaźnika wymaga czytania dysku, dlatego też realizacja tego typu dostępu jest niewydajna. Można tu wprowadzać modyfikacje jak zastosowanie tablicy przydziału plików (FAT). Stosuje się to w MS-DOS i OS/2.
PRZYDZIAŁ LISTOWY skupia wskaźniki w jednym miejscu - w bloku indeksowym. Każdy plik ma własny blok indeksowy, będący tablicą adresów bloków dyskowych. Pozycja o numerze i w bloku indeksowym wskazuje na blok i danego pliku. Katalog zawiera adres bloku indeksowego. Aby przeczytać blok i używa się wskaźnika z pozycji o numerze i w bloku indeksowym, za którego pomocą znajduje się odpowiedni blok do czytania. Podczas tworzenia pliku wszystkie wskaźniki w bloku indeksowym otrzymują wartość nil. Gdy blok i jest po raz pierwszy zapisywany, wówczas usuwa się go z listy wolnych przestrzeni; jego adres zostaje umieszczony w pozycji o numerze i w bloku indeksowym. Zamówienie na dodatkowy obszar może spełnić wolny blok znajdujący się gdziekolwiek na dysku. Ten sposób przydziału powoduje marnowanie miejsca na dysku. Nakład na wskaźniki bloku indeksowego jest na ogół większy niż nakład na wskaźniki przy przydziale listowym. Pliki są najczęściej małe.
52. Opisz poznane metody planowania dostępu do dysku.
Jest ważne aby usługi dyskowe były możliwie jak najszybsze, ponieważ wiele zadań jest mocno uzależnionych od dysku ze względu na ładowanie oraz kontakt z plikami wejściowymi i wyjściowymi. System operacyjny musi skrócić średni czas obsługi dysku dzięki planowaniu wykonywania zamówień na dostęp do dysku.
METODA FCFS jest najprostszą metodą planowania dostępu do dysku. Jest to planowanie na zasadzie pierwszy nadszedł pierwszy obsłużony. Algorytm ten jest łatwy do zaimplementowania i wewnętrznie poprawny, jednak przy jego zastosowaniu średni czas może być nie najlepszy. Wada tego planowania ujawnia się w gwałtownych wychyleniach głowicy.
METODA SSTF. Dąży się to do łącznej obsługi wszystkich zamówień sąsiadujących z bieżącym położeniem głowicy, zanim nastąpi jej przemieszczenie w odleglejszy rejon w celu realizacji innego zamówienia. To założenie stanowi podstawę dyskowego algorytmu planowania noszącego nazwę najpierw najkrótszy czas przeszukiwania (shortest seek-time-first). Ponieważ czas przeszukiwania jest ogólnie biorąc proporcjonalny do różnicy numerów ścieżek między zamówieniami, algorytm ten implementuje się za pomocą przesuwania głowicy do najbliższej ścieżki z kolejki zamówień.
METODA SCAN. Do tej metody prowadzi rozpoznanie własności dynamicznych koleji zamówień. Głowica czytająco-pisząca startuje od jednego końca dysku i przemieszcza się w kierunku przeciwległego końca, obsługując zamówienia, które napotka przechodząc nad kolejnymi ściezkami, aż dotrze do drugiego końca dysku. Na drugim końcu zmienia się kierunek ruchu głowicy i obsługa jest kontynuowana. Głowica nieprzerwanie przeszukuje dysk od końca do końca.
METODA C-SCAN jest wariantem algorytmu SCAN, zaprojektowanym w trosce o bardziej równomierny czas czekania. Tak jak w przypadku planowania metodą SCAN, w algorytmie C-SCAN przesuwa się głowicę od jednego końca dysku do drugiego, obsługując napotykane po drodze zamówienia. Jednak gdy głowica osiągnie przeciwległy koniec, wówczas wraca natychmiast na początek dysku, bez podejmowania obsługi jekiegokolwiek zamówienia w drodze powrotnej. Planowanie tą metodą traktuje dysk jak cykliczną powierzchnię, na której ostatnia ścieżka przylega do ścieżki pierwszej.
METODA LOOK. W dwóch poprzednich metodach głowica przemieszcza się zawsze od jednego skrajnego położenia na dysku do drugiego. W praktyce żaden z tych algorytmów nie jest implementowany w ten sposób. Najczęściej głowica przesuwa się do skrajnego zamówienia w każdym kierunku. Kiedy już nie ma zamówień w bieżącym kierunku, wtedy głowica zaczyna przesuwać się w przeciwnym kierunku. Takie wersje metod planowania SCAN i C-SCAN zwą się odpowiednio planowaniem LOOK (od popatrz) i C-LOOK.
53. Opisz podstawowe cechy systemu operacyjnego Unix.
System Unix jest systemem z podziałem czasu. Umożliwia on wieloprocesorowość (każdy proces może łatwo tworzyć nowe procesy). Do planowania przydziału czasu procesora wykorzystano prosty algorytm priorytetowy. Pliki dyskowe i urządzenia wejścia-wyjścia traktowane są możliwie jednolicie (tzn. np. stacja dysków traktowana jest jako katalog). Unix jest systemem, który stworzono z myślą o programistach dlatego znajduje się w nim wiele udogodnień dla nich. System powstał głównie w języku „C”. Podobnie jak większość systemów składa się on z jądra i programów systemowych. W jądrze jest zrealizowany system plików, planowanie przydziału procesora, zarządzanie pamięcią i inne zadania systemu operacyjnego do których dostęp mamy za pomocą funkcji systemowych. Charakterystyczną cechą systemu jest to, że stara się on zapobiegać sytuacjom krytycznym podczas gdy wiele innych systemów stara się naprawiać takie sytuacje. W miarę rozwoju systemu dodawane są nowe elementy takie jak: interfejs do pracy w systemie okien, praca w sieci. Unix używany jest do: organizacji pracy w sieciach, grafice, operacji w czasie rzeczywistym.
54. Jakie funkcje realizuje interfejs programisty systemu Unix? Omów zasadę tworzenia i usuwania procesów.
Interfejs programisty określają funkcje systemowe systemu Unix. Funkcje systemowe można podzielić na trzy kategorie: manipulujące plikami, sterujące procesami, manipulujące informacją.
1. Manipulowanie plikami.
Plik w systemie Unix jest ciągiem bajtów, jądro systemu nie narzuca struktury na plik. Pliki zorganizowane są w drzewiastą strukturę katalogów. Plik może być znany pod więcej niż jedną nazwą w jednym lub większej liczbie katalogów. Takie zwielokrotnione nazwy nazywane są dowiązaniami. Oprócz dowiązań zwykłych (twardych) stosuje się również dowiązania symboliczne (miękkie). Różnią się one tym mogą wskazywać na katalog i wykraczać poza granice systemu plików. Funkcje systemowe wykorzystywane do operacji na plikach:
1. create - tworzy nowy plik jak już istniał to obcina jego zawartość.
2. open - otwiera istniejący plik, zwraca deskryptor do pliku.
3. read, write - odczyt, zapis bajtów do pliku.
4. close - zamyka plik.
5. trunc - redukuje długość pliku do zera.
6. lseek - ustawienie pozycji w pliku.
7. dup, dup2 - tworzy nowy deskryptor będący kopią istniejącego.
8. stat - zwraca informacje o pliku.
9. rename - zmiana nazwy pliku.
10. chmod - zmiana atrybutów pliku.
11. chown - zmiana właściciela pliku.
12. link, symlink - utworzenie dowiązania zwykłego i symbolicznego.
13. unlink - usunięcie dowiązania jeśli jest to ostanie dowiązanie to usuwany jest plik.
Funkcje systemowe wykorzystywane do operacji na katalogach:
1. mkdir, rmdir - tworzenie i usuwanie katalogu.
2. opendir, closedir - otwarcie, zamknięcie katalogu.
3. readdir - przeczytanie katalogu.
- Nadzorowanie procesów.
Procesem jest wykonujący się program posiada on swój identyfikator, który jest liczbą całkowitą. Nowy proces tworzy się funkcją systemową fork, która przekazuje zero do nowego procesu, a do procesu macierzystego identyfikator procesu potomnego. Nowy proces zawiera kopię przestrzeni adresowej procesu pierwotnego. Na ogół po rozwidleniu jeden z dwu procesów używa funkcji execve, aby zastąpić przestrzeń swojej pamięci wirtualnej nowym programem. Proces może zakończyć działanie za pomocą funkcji exit, która przekazuje identyfikator tego procesu, a jego proces macierzysty może oczekiwać na to korzystając z funkcji wait. Funkcja wait3 jest podobna ale pozwala procesowi macierzystemu na zebranie informacji o potomku. Jeśli proces potomny załamie się to system symuluje wywołanie funkcji exit. W czasie pomiędzy wykonaniem przez potomka funkcji exit, a zakończeniem przez przodka funkcji wait potomek staje się mumią. Jeżeli proces macierzysty mumii zakończy działanie wcześniej niż potomny, to mumię dziedziczy proces inicjujący. Najprostszym sposobem komunikacji między procesami są łącza komunikacyjne (pipes). Tworzy się je przed operacją fork. Łącze komunikacyjne jest kolejką bajtów pomiędzy procesami. Dostęp do łącza komunikacyjnego odbywa się za pomocą deskryptora łącza. Jeden proces pisze do łącza, a drugi czyta z niego. Czytanie z pustego łącza i pisanie do pełnego powoduje wstrzymanie procesu do momentu gdy jego stan ulegnie zmianie.
Wszystkie procesy użytkownika są potomkami procesu init. Każdy aktywny port terminala ma aktywny proces getty, który określa początkowe parametry linii terminala za pomocą procesu login. Proces login pobiera od użytkownika hasło i jeśli jest ono właściwe to rozpoczyna działanie procesu shell i ustala liczbowy identyfikator użytkownika. Identyfikator ten używany jest przez system min. do określania praw dostępu do plików. Proces shell rozwidla się w celu wykonania poleceń użytkownika.
Sygnały są udogodnieniem pozwalającym obsługiwać sytuacje wyjątkowe na podobieństwo przerwań programowych. Sygnał może być wygenerowany przez przerwanie z klawiatury, błąd w procesie lub za pomocą kilku zdarzeń asynchronicznych. Prawie każdy sygnał może być wytworzony za pomocą funkcji kill. Przykładowe sygnały:
1. SIGINT zatrzymanie wykonywania polecenia przed jego zakończeniem
2. SIGQUIT sygnał zakończenia
3. SIGKILL usuwanie procesu
Przy wykonywaniu wspólnych zadań często współpracują ze sobą grupy powiązanych ze procesów. Np. procesy mogą korzystać z łączy komunikacyjnych tworzyć potoki i komunikować się za ich pomocą. Proces zwykle dziedziczy grupę procesów po swoim przodku. Funkcja setpgrp pozwala na zmianę grupy.
- Pobieranie informacji systemowych.
Przykładowe funkcje to:
1. getitimer, setitimer - pobieranie w mikrosekundach zawartości zegara interwałowego.
2. gettimeofday, settimeofday - pobieranie bieżącego czasu.
3. getpid, getgid - pobieranie identyfikatora procesu, grupy.
4. gethostname - pobranie nazwy maszyny.
- Procedury biblioteczne.
Interfejs funkcji systemowych jest wspomagany przez procedury biblioteczne. Biblioteki zawierają zbiór funkcji: wejścia-wyjścia, matematycznych, sieciowych, konwersji danych itd.
55. Jakie funkcje pełni w systemie Unix interfejs użytkownika.
Zarówno programista jak i użytkownik ma ją do dyspozycji zbiór gotowych programów systemowych np.:
1. rmdir, mkdir - usuwanie, tworzenie katalogu.
2. pwd - drukowanie nazwy bezwzględnej katalogu.
3. ls - listowanie zawartości katalogu.
4. cp, mv - kopiowanie, przenoszeni pliku.
5. rm - usuwanie pliku.
6. more - przeglądanie zawartości pliku.
7. ed, sed, emacs, vi - edytory tekstu.
8. mail - usługi pocztowe.
- Interpretator poleceń.
Zarówno programy systemowe jak i programy napisane przez użytkownika są wykonywane przez interpretator poleceń (shell). W shell'a wbudowana jest tylko niewielka liczba poleceń większość są to gotowe wykonywalne programy. Wykonanie polecenia odbywa się za pomocą funkcji fork, po której występuje funkcja execve ładująca plik z poleceniem. Shell wykonuje wtedy najczęściej funkcję wait (czeka na zakończenie wykonania się polecenia). Aby shell nie oczekiwał na zakończenie polecenia należy na końcu wiersza z poleceniem dostawić znak „&” (poleceni wykonywane jest wtedy w tle). Procesy, przy których shell musi czekać nazywają się pierwszoplanowymi.
- Standardowe wejście-wyjście.
Procesy mogą dowolnie otwierać pliki, lecz większość z nich pracuje przy założeniu, że w chwili ich rozpoczęcia są otwarte trzy pliki o deskryptorach (0-standardowe wejście,1-standardowe wyjście,2-standardowe wyjście diagnostyczne). Wszystkie te trzy deskryptory plików są często otwarte na terminalu użytkownika. Dzięki czemu program może czytać ze standardowego wejścia to, co użytkownik napisze oraz wysyłać wyniki na ekran użytkownika poprzez pisanie do standardowego wyjścia. Zmiana standardowego pliku jest nazywana przeadresowaniem wejścia-wyjścia (np. % ls > plik; zawartość aktualnego katalogu zostanie zrzucona zamiast na ekran do pliku).
- Potoki, filtry i scenariusze.
Każda pionowa kreska informuje shell, że wyjście poprzedniego polecenia ma być przekazane jako wejście do następnego polecenia (np. % ls | pr | lpr). Do przeniesienia danych od jednego procesu do drugiego używa się potoku. Jeden proces pisze na jednym końcu potoku, drugi zaś czyta z drugiego końca potoku. Polecenie takie jak pr, które przekazuje standardowe wejście do standardowego wyjścia przetwarzając je przy tym w pewien sposób nazywa się filtrem. Shell jest także językiem programowania. Plik poleceń dla shell'a nazywany jest scenariuszem.
Obecnie poza shell'em istnieje kilka interfejsów sterowania systemem Unix (min. X Window System).
56. Omów zarządzanie pamięcią realizowane w systemie Unix.
Ze względu na to, że Unix był projektowany dla komputerów o małej pamięci fizycznej nie zastosowano złożonych algorytmów zarządzania pamięcią. W Unixie wymienia się całe obszary pamięci procesów.
- Wymiana.
W systemach Unixowych poprzedzających wersję 3BSD zastosowano wymianę wyłącznie do obsługi rywalizacji między procesami. Jeśli rywalizacja jest za duża, to procesy są usuwane z pamięci operacyjnej do czasu, aż znajdzie się w niej wystarczająco dużo miejsca. Może to doprowadzić do tego, że proces wymagający większego obszaru pamięci niż pamięć główna nie zostaną w ogóle wykonane. Przydział pamięci głównej i przestrzeni wymiany odbywa się na zasadzie „pierwszy pasujący”. Gdy rozmiar pamięci procesu wzrasta, wówczas przydziela się nowy obszar pamięci wystarczający do pomieszczenia całego obrazu pamięci procesu. Nowy obszar pamięci zostaje skopiowany, zajęty poprzednio obszar pamięci zostaje zwolniony, a odpowiednie tablice są aktualizowane. Jeśli nie ma pojedynczego wystarczającego obszaru pamięci proces odsyłany jest na dysk. Decyzje o tym, który proces wysłać na dysk, a które wprowadzić do pamięci głównej podejmuje proces planujący (swapper). Proces ma większą szansę być odesłanym na dysk jeśli: pozostaje bezczynny, przebywa w pamięci głównej od dłuższego czasu lub jest bardzo duży. Szansa na wprowadzenie procesu do pamięci głównej jest większa jeśli: przebywa on dłuższy czas na dysku lub jest mały.
- Stronicowanie.
Stronicowanie wprowadzono do Unixa poczynając od wersji 3BSD. Stronicowanie wyeliminowało zewnętrzną fragmentację pamięci.
Stronicowanie na żądanie. Kiedy proces potrzebuje strony, której nie ma, wtedy w jądrze powstaje sygnał błędu strony, przydziela się ramkę pamięci głównej i czyta do niej właściwą stronę.
Algorytm zastępowania stron. W systemie 4.2BDS stosuje się zmodyfikowany algorytm zastępowania stron najdawniej używanych (LRU) z zegarem globalnym. Mapa pamięci głównej poza jądrem obiegana jest liniowo przez programową wskazówkę zegara. Gdy wskazówka zegara znajdzie się nad ramką, która jest oznaczona jako będąca w użyciu lub wolna wówczas ramka ta zostaje nietknięta, a wskazówka zegara przechodzi do następnej ramki. W przeciwnym razie lokalizuje się odpowiadającą tej ramce stronę kodu lub pozycję w tablicy stron procesu. Jeśli ta pozycja jest już unieważniona, to ramkę tą dodaje się do listy ramek wolnych. W przeciwnym razie unieważnia się pozycję w tablicy stron, lecz może to podlegać reklamacji (jeśli strona nie zostanie zmieniona przed następnym do niej odniesieniem, to pozycja w tablicy z powrotem nabierze ważności). Jeśli strona jest „zabrudzona” to zanim jej ramkę doda się do listy wolnych ramek, strona musi być zapisana na dysku. Wskazówka zegara w algorytmie LRU jest implementowana za pomocą demona stron, który jest procesem nr 2. Ilekroć liczba wolnych ramek spadnie poniżej pewnego poziomu, określanego wartością zmiennej lotsfree, tylekroć budzi się demon stron.
57. Zarządzanie procesami w systemie Unix.
Zasadniczą różnicą między Unixem, a wieloma innymi systemami jest łatwość tworzenia i manipulowania wieloma procesami. Procesy są reprezentowane w systemie Unix przez rozmaite bloki sterujące przechowywane w jądrze. Jądro używa zawartej w tych blokach informacji do sterowania procesami i planowania przydziału procesora.
- Bloki kontrolne procesu.
Podstawową strukturą danych związaną z procesami jest struktura procesu. Zawiera ona wszystkie niezbędne informacje o procesie, potrzebne na wypadek jego wymiany (identyfikator procesu, wskaźniki do innych bloków kontrolnych, priorytet). Struktury procesów gotowych do wykonania są powiązane ze sobą za pomocą planisty przydziału procesora i tworzą listę dwukierunkową (kolejka procesów do wykonania).
Wirtualna przestrzeń adresowa procesu użytkownika jest podzielona na segmenty: rozkazów, danych i stosu. Segmenty danych i stosu znajdują się zawsze w tej samej przestrzeni adresowej, ale mogą rosnąć niezależnie i zwykle w przeciwnych kierunkach. Każdy proces z dzielonym kodem programu ma w swojej strukturze wskaźnik do struktury tekstu. Sama struktura tekstu przechowuje informacje o tym, ile procesów używa danego segmentu rozkazów (włącznie ze wskaźnikiem do listy ich struktur procesów) oraz gdzie na dysku znajduje się tablica stron danego segmentu rozkazów, potrzebna podczas jego wymiany.
Tablica stron przechowuje informacje o odwzorowaniu wirtualnej pamięci procesów na pamięć fizyczną. Struktura procesu zawiera wskaźnik do tablicy stron.
W strukturze użytkownika przechowywane są informacje o procesie potrzebne tylko wtedy gdy proces rezyduje w pamięci. Struktura użytkownika jest odwzorowywana na wirtualną przestrzeń danych jądra. Gdy proces nie jest wykonywany wówczas znajduje się tam kopia bloku kontrolnego procesu w celu przechowania uniwersalnych rejestrów procesu, wskaźnika stosu, licznika rozkazów, oraz rejestrów bazowych tablicy stron. Istnieje obszar do przechowywania parametrów funkcji systemowych oraz ich wartości.
Każdy proces ma zarówno fazę użytkownika, jak i fazę systemową. Większość zwykłych prac wykonywana jest przez proces użytkownika, lecz w chwili wywołania funkcji systemowej do jej wykonania przystępuje proces systemowy. Faza systemowa nigdy nie jest wykonywana jednocześnie z fazą użytkownika. Proces systemowy ma inny stos niż proces użytkownika.
- Planowanie przydziału procesora.
Planowanie przydziału procesora w systemie Unix zaprojektowano z myślą o procesach interakcyjnych. Procesy otrzymują małe kwanty czasu procesora wg algorytmu priorytetowego, który dla zadań ograniczonych przez procesor redukuje się do algorytmu rotacyjnego.
Każdemu procesowi przypisuje się priorytet planowania. Większe liczby oznaczają niższe priorytety. Procesy wykonujące operacje dyskowe lub inne ważne prace mają priorytety ujemne. Im więcej proces zajmuje czasu procesora, tym niższy staje się jego priorytet (i na odwrót), tak że w planowaniu przydziału procesora istnieje ujemne sprzężenie zwrotne.
Proces oczekujący na jakieś zdarzenie może zostać uśpiony funkcją systemową sleep, a następnie obudzony funkcją wakeup.
58. Komunikacja międzyprocesowa w systemie Unix.
Wiele zadań w czasie wykonywania wymaga komunikacji między procesami.
- Gniazdka.
Najbardziej charakterystycznym mechanizmem komunikacji międzyprocesorowej w systemie Unix jest potok. Umożliwia on niezawodny jednokierunkowy przepływ strumienia bajtów między dwoma procesami. Implementuje się go w postaci zwykłego pliku, z kilkoma wyjątkami. Potok nie ma nazwy w systemie plików jest tworzony funkcją systemową pipe. Rozmiar potoku jest ustalony i proces, który chce pisać do pełnego potoku zostaje zawieszony. Jeżeli potoki są małe to mogą być przechowywane w pamięci.
W systemie 4.3 BSD potoki są zrealizowane jako specjalny przypadek mechanizmu gniazdka. Mechanizm gniazdka pozwala utworzyć ogólny interfejs nie tylko dla potoków, które są lokalne dla danej maszyny, lecz także do pracy w sieci. Gniazdko będące w użyciu ma zazwyczaj związany ze sobą adres.
Istnieje kilka typów gniazdek, które reprezentują różne klasy usług:
1. Gniazdka strumieniowe - umożliwiają dwukierunkowe przekazywanie sekwencyjnych strumieni danych. Przy przesyłaniu żadne dane nie giną ani nie są podwajane; nie ma też ograniczeń na rekordy (protokół TCP).
2. Gniazdka pakietów sekwencyjnych - tworzone są strumienie danych na podobieństwo gniazdek strumieniowych, ale stosuje się ograniczenia rekordów (protokół AF_NS w sieci XEROX NS).
3. Gniazdka datagramów - przesyłają w każdym kierunku komunikaty mające zmienną długość. Nie gwarantują jednak, że komunikaty dotrą w tym samym porządku, w którym zostały wysłane, że nie będą powtórzone, ani też, że nadejdą w ogóle. Jeśli natomiast jakiś komunikat dotrze do celu, to zawarte w nim rekordy będą miały zachowaną długość (protokół UDP).
4. Gniazdka niezawodnie dostarczanych komunikatów - gwarantują dostarczenie przesyłanych komunikatów, które poza tym przypominają komunikaty przekazywane za pomocą gniazdek datagramów. Obecnie nie implementuje się tego typu gniazdek.
5. Gniazdka surowe - umożliwiają procesom bezpośredni dostęp do protokołów implementujących inne typy gniazdek.
Z gniazdkiem jest związanych kilka specyficznych funkcji systemowych:
1. socket - funkcja tworzy gniazdko zwracana jest liczba całkowita będąca deskryptorem gniazdka.
2. bind - funkcja nadaje nazwę gniazdka, gdyż aby inny proces mógł zaadresować gniazdko musi ono mieć nazwę.
3. connect - inicjuje połączenie z gniazdkiem.
4. read, write - funkcje do czytania i przesyłania.
5. close - zakończenie połączenia.
6. shutdown - zakończenie jednego tylko kierunku łączności w połączeniu dwukierunkowym.
- Udogodnienia komunikacji sieciowej.
Prawie wszystkie obecne systemy Unix'a zawierają udogodnienia łączności sieciowej UUCP, z której najczęściej korzysta się za pośrednictwem linii telekomunikacyjnych. Udogodnienia łączności sieciowej są w prawie całości zaimplementowane jako procesy użytkownika i nie są częścią właściwego systemu operacyjnego. Procesy użytkowników komunikują się za pomocą protokołów sieciowych (to samo dotyczy procesów wykonywanych na różnych maszynach) poprzez gniazdka, które odpowiadają warstwie sesji modelu ISO i są odpowiedzialne za nawiązanie i nadzorowanie łączności.
1
4