Systemy operacyjne

(Uwaga: ten tekst nie był aktualizowany od 1998 roku!)

Komputer bez systemu operacyjnego, jest prawie jak nieprzytomny człowiek. Chociaż działa, to nie ma z nim żadnego kontaktu. Podobnie jak Pan Bóg ulepił człowieka z gliny i tchnął w niego życie, tak teraz człowiek po skonstruowaniu komputera z układów scalonych musiał jeszcze tchnąć w niego życie w postaci systemu operacyjnego…

Włączając komputer nie myślimy zwykle o tym, co się z nim dzieje aż do chwili, gdy jest już gotowy do pracy. Mówimy, że w tym czasie ładuje się system operacyjny. Ale czym właściwie jest ten system operacyjny i dlaczego po każdym włączeniu komputera trzeba go ładować od nowa? Czy nie można go załadować raz na zawsze? Czy można używać z komputera bez tego systemu operacyjnego? Na te pytania postaram się udzielić – w miarę możliwości – wyczerpującej odpowiedzi. A wiec…

Pytanie numer jeden brzmi: Jaka jest funkcjonalna różnica miedzy zwykłym kalkulatorem, a komputerem?

Wykonując obliczenia na kalkulatorze na przemian wprowadzamy dane oraz wskazujemy operacje, które mają być na nich od razu wykonane. Pomysł na komputer polega na tym, żeby wszystkie operacje najpierw zapamiętać, a potem wykonywać je automatycznie dla rożnych zbiorów danych. Dlatego właśnie integralną częścią każdego komputera jest tzw. pamięć operacyjna, w której pamiętane są zarówno dane, jak i operacje na nich wykonywane (zwane także instrukcjami lub rozkazami). Wykonywaniem rozkazów zajmuje się układ elektroniczny zwany procesorem. Procesor ma także swoją pamięć podręczną (ang. cache memory) oraz rejestry, służące do przechowywania rożnych zmiennych stanu, tymczasowych danych oraz adresów miejsc w pamięci.

Właściwie jedynym rejestrem, który będzie nas tutaj interesował jest licznik rozkazów (ang. Instruction Pointer), w którym procesor pamięta adres kolejnego rozkazu do wykonania. W dużym uproszczeniu cykl pracy procesora polega na:

  1. pobraniu z pamięci rozkazu wskazywanego przez licznik,
  2. zwiększeniu licznika o 1,
  3. wykonaniu rozkazu na odpowiednich danych,
  4. zapisaniu wyniku w pamięci albo w jednym z rejestrów,
  5. powrót do punktu 1).

Na tej zasadzie działały pierwsze komputery. Z biegiem lat zmniejszała się ich wielkość i cena, zwiększała się szybkość procesora i ilość dostępnej pamięci, zmieniał się zbiór rozkazów możliwych do wykonania przez procesor, ale zasada działania rożni się tylko w szczegółach. Dziś użytkownicy nie muszą się martwić o faktyczny sposób działania komputera. Jest to przed nimi ukryte pod wieloma warstwami specjalistycznego oprogramowania.

Oprogramowanie stanowi zbiór programów, których celem jest lepsze wykorzystanie komputera. Programy zawarte w pakiecie oprogramowania systemowego nazywa się programami systemowymi (ang. system programs). Odróżnia się je od programów użytkowych (ang. application programs) napisanych przez programistów w celu rozwiązywania poszczególnych problemów. Większość programów systemowych dostarcza producent komputera. Użytkownik, który kupuje lub dzierżawi komputer, otrzymuje zwykle razem z komputerem całe dostępne oprogramowanie potrzebne do jego skutecznego funkcjonowania. Oprogramowanie systemowe stanowi nieodłączną cześć całego systemu komputerowego. Kompensuje ono różnice istniejące miedzy potrzebami użytkownika i możliwościami układowymi komputera. Komputer nie mający żadnego oprogramowania systemowego byłby bardzo nieefektywny i najprawdopodobniej nie nadawałby się do niczego. Często nawet trudno jest określić gdzie kończy się „sprzęt”, a zaczyna system operacyjny, a także gdzie kończy się system, a zaczyna program użytkowy. Niektórzy zaliczają BIOS komputera do systemu operacyjnego ponieważ producenci komputerów często dostosowują swoje BIOS-y do określonego systemu. Oprogramowanie systemowe można podzielić na sześć rożnych kategorii:

  1. TRANSLATORY tłumaczą programy napisane w rożnych językach programowania na język wewnętrzny danego komputera (kod maszynowy), czyli rozkazy dla procesora (np. firma Microsoft rozprowadzała kiedyś razem z DOS-em język GW-BASIC)
  2. PROGRAMY BIBLIOTECZNE dostarczające programiście procedur standardowych, bowiem pierwsze systemy miały na celu przede wszystkim ułatwienie pracy programistom. Dzisiaj praca programisty systemowego jest bardzo skomplikowana, ale jednocześnie łatwiejsza (np. dzięki programowaniu obiektowemu)
  3. PROGRAMY USŁUGOWE (tzw. sterowniki) ułatwiające komunikację między poszczególnymi częściami komputera, miedzy komputerem i użytkownikiem oraz ostatnio także pomiędzy rożnymi komputerami (sieci komputerowe).
  4. PROGRAMY WPROWADZAJĄCE ułatwiające wczytywanie innych programów do pamięci. Są one głęboko wbudowane w strukturę systemu operacyjnego, często ich działanie nie jest w ogóle widoczne dla użytkownika i dlatego dzisiaj praktycznie się ich nie wyróżnia.
  5. PROGRAMY DIAGNOSTYCZNE ułatwiające konserwację komputera i testowanie sprawności jego urządzeń, a także kontrolujące poprawność działania samego systemu operacyjnego.
  6. PROGRAMY ANTYWIRUSOWE dołączyły stosunkowo niedawno do programów systemowych wskutek szybkiego mnożenia się w sieciach komputerowych rożnych programów wirusowych, które potrafią narobić wiele szkód w systemie komputerowym. Współcześnie nie są one na szczęście w stanie uszkodzić sprzętu, ale mogą powodować – czasami nawet groźniejsze – uszkodzenia danych. Rzeczą naturalną jest, że należy się przed nimi chronić.
  7. SYSTEM OPERACYJNY jest programem nadzorującym pracę wszystkich urządzeń systemu komputerowego (pamięci operacyjnej, urządzeń pamięci masowej, urządzeń wejścia wyjścia) tworząc wspólne środowisko pracy dla innych programów.

System operacyjny pełni następujące funkcje:

  • zapewnia obsługę dialogu pomiędzy użytkownikiem a komputerem,
  • nadzoruje wymianę informacji pomiędzy poszczególnymi urządzeniami,
  • organizuje zapis informacji na dyskach,
  • zarządza pamięcią operacyjną,
  • ułatwia tworzenie i uruchamianie innych programów,
  • zapewnia kontrolowanie pracy przez ADMINISTRATORA,
  • sygnalizuje błędy i niektóre automatycznie koryguje.

Ale przede wszystkim system ukrywa przed zwykłym użytkownikiem (a także przed programistą) większość – często bardzo różnorodnych – cech sprzętu. Nowoczesny system operacyjny składa się z tzw. jądra oraz ze wszystkich, wymienionych wyżej, programów systemowych. Zwraca się także uwagę na względną „przyjazność” komputera i łatwość jego obsługi, a także na możliwość komunikacji z użytkownikiem w języku innym niż angielski.

Ale nie zawsze tak było. Pierwsze komputery nie posiadały żadnego systemu operacyjnego. Były to olbrzymie i drogie maszyny, a ich programowanie było żmudne i czasochłonne. Pierwsi programiści pisali i uruchamiali programy z konsoli operatorskiej, z której mieli bezpośredni dostęp do wszystkich składowych komputera. Posługiwali się oni kodem dwójkowym albo ósemkowym. Każdy musiał ręcznie (ustawiając odpowiednie przełączniki) umieścić w pamięci komputera swój program oraz dane. Następnie ustawiał odpowiednią wartość licznika rozkazów i włączał procesor. Ten z kolei wykonywał instrukcje programu aż do napotkania instrukcji zatrzymania procesora. Wyniki programu otrzymywano w postaci święcących się lampek. Z czasem podłączono do komputera czytniki kart perforowanych albo taśm papierowych. Przyspieszyło to znacznie wprowadzanie programów do pamięci. Wyniki zaczęto drukować na drukarkach lub dziurkować na taśmach papierowych. Z czasem powstało oprogramowanie pomocnicze, takie jak programy obsługi urządzeń i specjalne programy do wczytywania innych programów. Powstał specjalny etat operatora, człowieka który zarządzał zasobami komputera. Programiście pozostawiono tylko programowanie. Stało się ono dzięki temu mniej żmudne, ale wydłużył się czas realizacji programu. Programista przynosił ze sobą rolkę taśmy papierowej albo paczkę kart perforowanych (mam kilka – trzymam je dla jakiegoś muzeum) i przekazywał je operatorowi, a ten wyznaczał mu termin zgłoszenia się po wyniki (na początku trwało to nawet do 3 dni). Operator spełniał praktycznie rolę pierwszego systemu operacyjnego. Jego zadanie było bowiem takie samo, jakie dzisiaj się przed nimi stawia, tzn. ułatwianie korzystania ze sprzętu komputerowego oraz troska o jego efektywne wykorzystywanie. Wczesna historia rozwoju systemów operacyjnych to także historia stopniowego przejmowania roli operatora przez oprogramowanie systemowe.

Mimo swoich najlepszych chęci operator był jednak o wiele wolniejszy od komputera. W czasie kiedy czytnik wprowadzał program do pamięci, procesor był bezczynny, a mógłby przecież wykonać niejeden program. Pierwsze systemy operacyjne miały za zadanie wyeliminować tę bezczynność. Zajmował się tym niewielki program zwany monitorem, który umieszczano w pamięci komputera na cały czas jego pracy. Był to wiec pierwszy program rezydentny. Wczytywał on programy do pamięci, ustawiał w tzw. kolejce do wykonania i wykonywał je potem w odpowiedniej ustalonej kolejności. Gdy operator uruchamiał programy, wiedział które karty zawierają program, a które dane i jakiego kompilatora należy użyć. Wprowadzenie automatycznego kolejkowania programów wymagało pewnej formy przekazywania tych informacji bezpośrednio do monitora. Ktoś wtedy wpadł na pomysł zastosowania tzw. kart sterujących. Karta sterująca określała jaki program należy wykonać i skąd wziąć do niego dane, a także za ile kart wczytana zostanie następna karta sterująca. Do realizacji swojego zadania użytkownik mógł zażądać wykonania kilku programów w ustalonej kolejności. Na karcie początkowej umieszczano nawet informacje potrzebne do rozliczeń: identyfikator użytkownika, jego konto i priorytet. Powstał wiec specjalny język sterowania zadaniami. Monitor taki składał się z trzech części:

  • interpretatora kart sterujących,
  • procedury ładującej program do pamięci,
  • procedury zajmującej się wejściem i wyjściem (np. pisaniem na drukarkę).

Monitory były w zasadzie pierwszym „programowym” wcieleniem systemu operacyjnego. Ich celem było ułatwienie pracy programiście i operatorowi, a także dbanie o efektywne wykorzystanie czasu procesora. Stały się one przodkiem systemów operacyjnych, z których dzisiaj każdy ma program ładujący, zestaw procedur wejścia/wyjścia oraz interpretator poleceń. Różnica polega na tym, że polecenia są wydawane przy pomocy klawiatury i myszki, wyniki pojawiają się najczęściej na ekranie, a na drukarce drukuje się tylko na żądanie użytkownika. Zmienił się także język poleceń. Na przykład w systemie MS-DOS interpretator poleceń, to program COMMAND.COM, podstawowe operacje wejścia/wyjścia wykonuje program zawarty w pliku IO.SYS, a reszta systemu (np. funkcje systemowe int21h) znajduje się w pliku MSDOS.SYS.

Sterowanie zadaniami funkcjonalnie podobne do kart sterujących można zapisywać w plikach o specjalnym formacie typu *.BAT (ang. batch files). Zawierają one instrukcje dla interpretatora. Język poleceń interpretatora powinien być prosty, łatwy do zapamiętania i spójny logicznie (tzn. łatwo go zrozumieć, a wszystkie polecenia są wydawane na podobnych zasadach).

Następny krok w rozwoju systemów operacyjnych to programowa realizacja tzw. SPOOLINGU (ang. Simultaneous Peripheral Operation On-Line). Polegało to (i nadal polega) na wykonywaniu obliczeń przez procesor jednocześnie z wykonywaniem operacji wejścia/wyjścia. Faktycznie w pamięci znajdował się specjalny program, tzw. SPOOLER, a procesor dzielił swój czas pomiędzy program użytkownika, a spooler. Spooler najczęściej wczytywał program z kart na dysk, a następnie z dysku korzystał program ładujący, ponieważ operacje dyskowe były kilkakrotnie szybsze. Historia systemów operacyjnych, to ciągła walka o szybsze przetwarzanie programów. Walka ta byłaby jednak z góry przegrana, gdyby nie towarzyszące jej udoskonalenia sprzętu.

Takim udoskonaleniem było odciążenie głównego procesora od operacji wejścia/wyjścia i przejęcie jego pracy przez pomocnicze procesory wejścia/wyjścia zwane też kanałami. Czasochłonnymi operacjami zajmuje się specjalny, prosty i tani procesor, a procesor główny może w tym czasie wykonywać obliczenia. W komputerze typu PC nadal zachowały się implementacje tych rozwiązań w postaci kanałów DMA (ang. Direct Memory Access). Kanały dzieli się na selektorowe i multiplekserowe. Z każdym kanałem może być jednocześnie połączonych nawet do 256 rożnych urządzeń. Kanał selektorowy może w danej chwili obsługiwać

tylko jedno szybkie urządzenie (np. dysk), a kanał multiplekserowy wiele urządzeń pod warunkiem, że są to urządzenia „powolne” (np. terminale, drukarki) aby kanał zdążył je wszystkie obsłużyć. Wprowadzanie kanałów umożliwiło nie tylko efektywny spooling, ale dało możliwości do konstrukcji pierwszych systemów wielozadaniowych. Zmiany w sprzęcie pociągnęły za sobą po raz kolejny zmiany w oprogramowaniu. System operacyjny musiał być wzbogacony o funkcje zajmujące się obsługą kanałów (takie jak: śledzenie stanu, przydzielanie i zwalnianie kanału oraz obsługa błędów, które mogły się pojawić).

Następnym ulepszeniem było wynalezienie przerwań. Kiedy procesor wykonuje pewien program istnieje możliwość przerwania jego pracy w wyniku jakiegoś zdarzenia, które musi być natychmiast obsłużone (np. zanik zasilania, naciśnięcie klawisza na klawiaturze, błąd pamięci, błąd dzielenia przez zero, próba wykonania nieznanej instrukcji, itp…). Procesor przerywa wtedy wykonywanie rozkazów, zachowuje w specjalnym obszarze pamięci (na tzw. stosie) dane dotyczące wykonywanego programu i przełącza się na podprogram obsługi przerwania, który wykonuje odpowiednie czynności związane z danym przerwaniem. Po zakończeniu obsługi przerwania procesor wraca do dalszej pracy od miejsca, w którym została ona przerwana. Wykorzystuje do tego dane zapisane wcześniej na stosie jednocześnie je z niego usuwając. Można też ignorować przerwania. Służą do tego specjalne rozkazy procesora. Każde przerwanie ma także swój priorytet i od niego zależy, które będzie obsłużone najpierw jeśli wystąpiły jednocześnie. Możliwe jest też tak zwane maskowanie przerwań, czyli zabronienie wykonywania określonych przerwań. Istnieją też tak zwane przerwania programowe. W odróżnieniu od przerwań sprzętowych (linie IRQ – ang. Interrupt Query), przerwania programowe mogą być wywoływane przez system operacyjny lub przez program użytkownika.

W nowoczesnych systemach często poprzez przerwania programowe udostępnia się programistom niektóre usługi systemu. Nazywa się to interfejsem API (ang. Application Programing Interface). System operacyjny musi ze swojej strony dostarczyć odpowiednich programów obsługi przerwań sprzętowych. Często też droga obsługi przerwania prowadzi kolejno przez zainstalowane podprogramy obsługi urządzeń (ang. device drivers), które wzbogacają możliwości systemu operacyjnego o obsługę nowych urządzeń.

Wprowadzenie przerwań spowodowało duży jakościowy skok w rozwoju systemów operacyjnych. Dzięki nim stała się możliwa realizacja asynchronicznych operacji wejścia/wyjścia (np. program może reagować na naciśniecie klawisza wtedy, kiedy został on naciśnięty i nie musi czekać na to zdarzenie w pętli tak, jak to było do tej pory). Dzięki umieszczeniu w komputerze zegara systemowego (także wywołującego odpowiednie przerwanie) stał się możliwy do realizacji podział czasu procesora, a w konsekwencji powstały systemy „wielorakie”, takie jak:

SYSTEM WIELOPROGRAMOWY – umożliwia jednoczesną obecność w pamięci kilku programów i stworzenie tzw. puli zadań do wykonania. W momencie, w którym działający program czeka na zakończenie operacji we/wy albo w innym momencie, kiedy procesor właściwie „nic nie robi” system podsuwa mu do wykonania kolejny program z puli zadań. Gdy ono również musiało być przerwane, przechodzi do następnego itd. Kiedy pierwsze zadanie przestawało czekać, to ponownie otrzymywało dostęp do procesora (tzn. system „kazał” procesorowi je wykonywać).

SYSTEM WIELOZADANIOWY – (zwany także systemem z podziałem czasu) jest to kolejne logiczne rozszerzenie wieloprogramowości. W takim systemie procesor przełącza się między zadaniami tak często, że użytkownik odnosi wrażenie jednoczesnego wykonywania się programów. Mówi się wtedy, że procesor dzieli swój czas na realizację wielu zadań.

SYSTEM WIELOPROCESOWY – program w trakcie jego wykonywania pod kontrolą systemu operacyjnego nazywamy procesem. W tym systemie jeden użytkownik może uruchomić wiele programów, a więc „jednocześnie” wykonywanych jest wiele procesów. Może nawet działać kilka jednakowych procesów, a każdy z nich na rożnych danych. Procesy mogą ze sobą także na rożne sposoby współpracować albo współzawodniczyć (np. o dostęp do zasobów).

SYSTEM WIELOPROCESOROWY – wieloprocesorowość to pojecie odnoszące się do komputera, który ma w swoich „bebechach” więcej niż jeden procesor. Taka architektura może wspierać wieloprocesowość. Wtedy każdy procesor może wykonywać inne zadanie, a procesy mogą się wykonywać równolegle (do tej pory mówiliśmy, że jednocześnie).

SYSTEM WIELODOSTĘPNY – system ten umożliwia jednoczesną pracę wielu użytkownikom podłączonym do niego za pomocą tzw. terminali. System taki uruchamia tyle procesów, ile jest użytkowników. Wtedy każdy taki proces obsługuje jednego z nich. System wielodostępny umożliwia wielu użytkownikom pracę interakcyjną (w odróżnieniu od pracy wsadowej), co oznacza w praktyce możliwość nadzoru wykonywania zadania na bieżąco. Programista może poprawiać błędy w swoim programie i uruchamiać go od nowa (a nie czekać godzinami na wyniki od operatora).

Niektórzy twierdzą, że o prawdziwych systemach operacyjnych można mówić dopiero od chwili, gdy zaczęto dodawać do nich przeróżne przymiotniki, zaczynające się od wielo-. Z tego punktu widzenia wcześniejsze systemy operacyjne można nazwać systemami sterowania. Wszystkie omówione tu cechy (oprócz wieloprocesorowości) są zależne od danego systemu operacyjnego. Wsparcia sprzętowego wymaga wieloprogramowość. Tu nie wystarczą bowiem kanały i mechanizm przerwań. Potrzebna jest sprzętowa ochrona przed niepowołanym dostępem do pamięci, dwa tryby pracy procesora oraz pewne nowe rozkazy dostępne tylko dla systemu operacyjnego.

Początkowo systemy operacyjne były pomyślane jako narzędzia obsługi skomplikowanych operacji wejścia/wyjścia – komunikacji z dyskami. Szybko jednak stały się rozległym pomostem pomiedzy komputerem a oprogramowaniem. Bez systemu operacyjnego każdy programista musiałby sam od podstaw tworzyć sposoby przedstawiania tekstu lub grafiki na ekranie, przesyłania danych do drukarki, komunikacji z dyskiem i mnóstwo innych funkcji, łączących oprogramowanie ze sprzętem. Jednak system operacyjny to coś więcej niż ułatwienie pracy programistom. Tworzy on wspólną platformę dla wszystkich programów, których używamy. Bez niego nie moglibyśmy zapisać na jednym dysku plików tworzonych przez dwa różne programy, ponieważ każdy z nich mógłby być zapisany według własnego formatu. System operacyjny dostarcza również narzędzi do wykonania zadań na zewnątrz programów użytkowych, takich jak usuwanie i kopiowanie plików, wyświetlanie list plików i wykonywanie zestawów poleceń w plikach wsadowych (ang. batch).

System operacyjny nie działa samodzielnie. Zależy on nie tylko od współpracy z programami dla niego napisanymi, ale także od harmonijnego współdziałania z BIOS-em i tzw. chipsetami płyt głównych. Gdy pewne części systemu operacyjnego są ładowane z dysku, najpierw są dodawane do BIOS-u, a następnie łączone przez programy obsługi urządzeń i wszystkie wykonują rutynowe funkcje sprzętowe. Byłoby uproszczeniem uważać system operacyjny jedynie za zestaw plików na dysku, który dostajemy wraz z komputerem. BIOS, programy obsługi urządzeń i system operacyjny wykonują łącznie wiele bardzo rożnych funkcji.

Dzisiejsze systemy operacyjne rozróżnia się przede wszystkim po sposobie zarządzania procesami i przydzielania im określonych zasobów. Do zasobów systemu zalicza się:

  • procesor,
  • pamięć operacyjną,
  • urządzenia wejścia/wyjścia (np. drukarki, pliki na dyskach, sieć komputerowa, ekrany, itd…)

System musi podjąć decyzję, który proces, kiedy i na jak długo otrzyma dostęp do danego zasobu. Stwarza to systemowi dużo problemów i kiedy nie może on sobie z nimi poradzić zawiesza się. System operacyjny pełni rolę gospodarza systemu komputerowego. Im lepszy gospodarz, tym lepiej są wykorzystywane zasoby i tym więcej użytkowników może on obsłużyć. Jednak interes pojedynczego użytkownika może być w sprzeczności z generalnym interesem systemu. Projektanci systemów nie potrafią (na razie) wyposażyć systemu w inteligencję, a więc muszą szukać algorytmów dobrych na każdą zaistniałą ewentualność.

Wynikiem zarządzania komputera przez system operacyjny jest zwiększenie jego efektywności. Efektywność systemu komputerowego jest mierzona jego przepustowością informatyczną (ang. throughput). Jest to ilość pracy wykonanej przez system w określonej jednostce czasu, np. w ciągu godziny. Przepustowość jest zwykle miernikiem sprawności układów komputera i jego oprogramowania. System operacyjny dostarczający skuteczne oprogramowanie przyczynia się także do zwiększenia przepustowości informatycznej systemu komputerowego.

Nowoczesny system operacyjny składa się z jądra (ang. kernel), powłoki (ang. shell), oraz wielu usługowych programów systemowych. Jądro stanowi od 5% do 10% całości systemu, ale jest w nim najistotniejsze. W skład jądra wchodzi centralny program nadzorujący wspierany przez procedury usługowe troszczące się o takie ważne szczegóły, jak pobieranie znaków z klawiatury, współpraca z pamięcią zewnętrzną i nadzór nad zegarem systemowym. Jądro tworzy podstawowe środowisko dla reszty systemu. Ukrywa maszynę fizyczną przed programami (a nawet przed sobą) pod postacią tzw. maszyny wirtualnej.

Mikrojądro jest to zbiór elementarnych procedur obsługi sprzętu. Tylko mikrojądro musi być w całości napisane w języku procesora (w języku maszynowym, albo w tzw. asemblerze). To właśnie procedury mikrojadra składają się na właściwą maszynę wirtualną. Procedury te wpisują znaki do odpowiedniego portu, obsługują przerwania, czytają informacje z dysku, itp. Są one jakby rozszerzeniem BIOS-u na potrzeby reszty systemu operacyjnego. Istotną cześć jądra (70-90%) stanowią procedury usługowe. Dotyczą one zarządzania pamięcią, kolejkowania użytkowników, szeregowania procesów, a także nadzoru nad stosem systemowym, rejestrami oraz innymi elementami środowiska podczas ładowania procesu do pamięci operacyjnej. Odpowiadają też za przerwania spowodowane np. sprzętowymi błędami pamięci. Procedury usługowe korzystają w całości z maszyny wirtualnej i są niezależne od sprzętu. Szeregowanie zadań, zarządzanie pamięcią, i sterowanie wykonaniem programów wymagają szybkiego reagowania. Dlatego ta cześć jądra znajduje się przez cały czas w pamięci.

Bezpośredni dostęp do procedur usługowych i maszyny wirtualnej uzyskuje się za pomocą funkcji systemowych (ang. system calls). Są to najczęściej tak skonstruowane przerwania programowe, aby dany proces wywołujący je miał kontakt z jądrem systemu. Działanie funkcji systemowych polega najczęściej na pobieraniu informacji z systemu, zapisywaniu informacji do urządzeń zewnętrznych oraz wywoływaniu procedur usługowych (np. operacje na plikach i katalogach, kontrola urządzeń wejścia/wyjścia, ustawianie czasu systemowego, itp). Wywołania funkcji systemowych można traktować jako instrukcje wykonywane przez maszynę wirtualną – można też powiedzieć, że to właśnie zbiór tych funkcji definiuje maszynę wirtualną. Podprogramy obsługi urządzeń (ang. device drivers), bezpośrednio sięgają do rejestrów sterujących urządzeń. Obsługują on przerwania zgłaszane przez urządzenia zewnętrzne i ich błędy. Są one – tak jak mikrojądro – całkowicie zależne od sprzętu. Nie są jednak integralną częścią jądra, ale tylko rozszerzają jego możliwości i wcale nie są konieczne do jego prawidłowego funkcjonowania.

System operacyjny zawsze jest projektowany adekwatnie do zadań, jakie ma spełniać. Pod tym względem można podzielić systemy na dwie grupy. Pierwszą stanowią te systemy ogólnego przeznaczenia (np. Unix), które są zwykle wieloprocesowe i wielodostępne, a nawet wieloprocesorowe (np. Windows NT). Muszą one być przygotowane na rożnego rodzaju oprogramowanie i odporne na manipulacje oraz bardzo często muszą zapewniać bezpieczeństwo danych. Druga grupa to systemy, w których czas wykonania konkretnych zadań jest bardzo istotny. Takie systemy nazywamy systemami czasu rzeczywistego lub systemami wbudowanymi (ang. embedded systems), gdyż są one zwykle częścią większej całości, w której komputer pełni rolę urządzenia sterującego. Są to wiec np. systemy monitorujące stan chorego na oddziale intensywnej terapii, sterujące linią produkcyjną w fabryce, pracą elektrowni atomowej, centrali telefonicznej, a nawet automatycznym pilotem w samolocie. Wymaga się od nich niezawodności i efektywności w działaniu, często kosztem ich uniwersalności. Zwykle wykonujące się w tych systemach procesy są dokładnie znane – o każdym wiadomo, ile czasu procesora potrzebuje w najgorszym przypadku i jak często ma być wykonywany. Można zatem z góry ustalić kolejność i wymogi pamięciowe procesów. Systemy te dzielą się na synchroniczne i asynchroniczne. System synchroniczny dzieli czas procesora na równe odcinki. W trakcie jednego z tych odcinków musi zdążyć się wykonać czas każdego z procesów, tak aby każdy proces był wykonany w całości w z góry określonym przedziale czasu. System synchroniczny ma wiele wad. Nie wykorzystuje w całości procesora, gdyż zakłada najgorszy przypadek i zawsze zostawia dla procesu w rezerwie więcej czasu. Trudno jest dodać nowy proces, gdyż wymagać to może zmiany całego systemu, a także sprzętu. Jednak dobrze zaprojektowany jest praktycznie niezawodny. System asynchroniczny oparty jest zwykle na przerwaniach i ich priorytetach. Gdy w kolejce do procesora pojawi się nowy proces o wyższym priorytecie (ważności) niż aktualnie wykonywany, powoduje to przerwanie pracy procesora i przydzielenie go nowemu procesowi. Cały problem polega tu na ustaleniu priorytetów. Można to robić statycznie (raz na zawsze) albo dynamicznie (w trakcie pracy). Takie systemy można jednak przeciążyć kiedy dostaną za dużo zadań do wykonania jednocześnie i wystąpi przepełnienie stosu. Współczesne systemy są na to jednak odporne, bo mają bardzo dużo pamięci.

Podstawowym problemem występującym w świecie komputerów jest przydział pamięci operacyjnej procesom. Na początku programy ładowano w ustalone, zawsze to samo miejsce w pamięci. Taka strategia miała wiele zalet, bo program mógł posługiwać się już znanymi adresami, tzw. adresami bezwzględnymi. Ładowanie takiego programu do pamięci było bardzo proste. Wystarczyło skopiować go w określone miejsce pamięci operacyjnej. Na przykład w DOS-ie programy takie maja nazwy z rozszerzeniem COM. Stworzenie możliwości istnienia w pamięci wielu programów naraz wiązało się ze znacznym skomplikowaniem operacji ładowania. Musiała zaistnieć możliwość załadowania programu w dowolne miejsce pamięci operacyjnej. Takie programy

mają w DOS-ie rozszerzenie nazwy EXE. Czasami jednak system potrzebuje przemieszczać procesy w pamięci, aby odzyskać pamięć zwolnioną przez inne procesy. To stało się możliwe dzięki wprowadzaniu nowego specjalnego rejestru procesora, tzw. rejestru bazowego. Rejestr bazowy zawiera adres początku programu, a wszystkie dane w programie są adresowane względem początku programu. Procesor automatycznie dodaje zawartość rejestru bazowego do każdego adresu tzw. adresu względnego, do którego odwoływał się program.

Obecnie możliwe jest także uruchamianie wielu programów (a wiec i tworzenie przez system wielu procesów) o wielkości przekraczającej ilość dostępnej pamięci operacyjnej w systemie (tzw. procesy olbrzymie). Przydział zwykłej pamięci operacyjnej jest przeróżnie realizowany. Praktycznie każdy system robi to inaczej i na sobie tylko właściwy sposób, a projektanci systemu zawsze twierdzą, że to właśnie ich sposób jest najlepszy. Przy każdym z algorytmów można jednak znaleźć przykłady „z życia wzięte”, które pomagają zobrazować działanie takiego algorytmu. Jeśli na przykład pamięć operacyjną potraktujemy jak parking dla samochodów, a procesy jak pojazdy o różnych parametrach, to problemy z przydziałem pamięci są takie same jak problemy z parkowaniem w dużym mieście. Właściwie można do woli konstruować algorytmy przydzielania pamięci, ponieważ dla pewnej kolejności „przyjeżdżania samochodów o rożnych wielkościach” każdy z nich może być raz najlepszym, a innym razem najgorszym sposobem. Najpopularniejsze metody to:

METODA STREF STATYCZNYCH – dla każdego pojazdu (motor, sam. oso boby, ciężarówka, tir) jest osobne, wcześniej przygotowane miejsce i kiedy na niego czeka, nie może być wykorzystane przez inny pojazd.

PIERWSZE DOPASOWANIE – każdy kierowca parkuje swój samochód na pierwszym wolnym miejscu, nawet jeśli jeździ motocyklem, może zaparkować na miejscu dla ciężarówek.

OSTATNIE DOPASOWANIE – każdy kierowca parkuje swój samochód na ostatnim wolnym miejscu niezależnie od jego wielkości.

NAJLEPSZE DOPASOWANIE – każdy pojazd parkuje w miejscu najlepiej dla niego pasującym,o czym decyduje parkingowy.

NAJGORSZE DOPASOWANIE – każdy pojazd parkuje się w największej wolnej przerwie, ponieważ kierowcy nie chcą się nigdzie wciskać (można przecież porysować lakier – nie tyle sobie, co komuś).

DEFRAGMENTACJA Z RELOKACJĄ – samochody na parkingu zostawia się „na luzie”, a w razie potrzeby, lub w przypadku odjechania jednego z nich, przepycha się je, tak aby uzyskać więcej wolnego miejsca. Tzw. fragmentacja powstaje wtedy, gdy jest dużo dziur, ale każda jest za mała aby pomieścić np. ciężarówkę. Defragmentacja polega na usuwaniu takich dziur przez przesuwanie samochodów.

STRONICOWANIE – to realizacja jakby parkingu wielopoziomowego, na którym samochody, które będą długo słały, parkuje się najwyżej (kierowca, który zatrzymuje się tylko na chwilę nie chce wchodzić po swój samochód wysoko po schodach). W miarę upływu czasu postoju samochodu postawionego najwyżej przenosi się go o piętro niżej, tak że kiedy klient przyjdzie odebrać samochód będzie on już na parterze. Stronicowanie nie likwiduje fragmentacji pamięci, ale po prostu jej nie uniemożliwia.

PAMIĘĆ WIRTUALNA – to jakby wysyłanie samochodów na inne, zaprzyjaźnione parkingi, o których wiemy, że mają wolne miejsca, a następnie przenoszenie samochodów bliżej klienta na koszt właściciela parkingu (musi mu wtedy bardzo zależeć na tym, żeby klient zaparkował właśnie u niego).

Realizacja zagadnienia uruchamiania programów większych niż ilość pamięci operacyjnej w systemie jest bardzo skomplikowana. Przez procesor tworzona jest tzw. wirtualna przestrzeń adresowa, z której adresów korzystają uruchamiane programy. Pamięć wirtualna znajduje się najczęściej na szybkim dysku twardym (może być też na innym komputerze podłączonym do sieci albo na taśmie tzw. streamera). Specjalny proces (tzw. proces wymiany) realizuje przerzucanie procesów z pamięci operacyjnej do pamięci pomocniczej (na dysk) i na odwrót. Proces olbrzymi może wykonywać się tylko w pamięci operacyjnej, więc jest on ładowany do niej kawałkami. Kiedy jednak pamięć operacyjna jest pełna, trzeba jej cześć zwolnić. Ale w jaki sposób? Co należy wybrać? Znane są obecnie dwa typy rozwiązań tego problemu. Pierwszy nazywa się tzw. strategią wymiany. Gdy uruchomiono wiele procesów, które w sumie są większe niż pamięć operacyjna, ale nie ma pojedynczego procesu, który przekracza jej rozmiar, przenosi się programy z pamięci na dysk nawet w całości (do pliku wymiany albo na partycję wymiany). To właśnie robi proces wymiany. Drugi sposób – wydający się lepszym rozwiązaniem – to metoda stronicowania. Pamięć operacyjną dzieli się na określonej wielkości ramki (ang. frames), najczęściej po 16 KB, a programy na jednakowej wielkości fragmenty zwane stronami. Każdą stronę programu można umieścić w jednej wolnej ramce. Każdej ramce odpowiada inny rejestr bazowy. Powstała specjalna tablica stron obsługiwana przez system operacyjny. System korzysta przy obsłudze storn z nowych, specjalnie zaprojektowanych rozkazów procesora, który wykonując program odwołujący się do konkretnej strony wywołuje odpowiednie przerwanie aby daną stronę sprowadzić do pamięci w razie jej braku. Trzeba jednak niektóre strony usuwać z pamięci, aby zwolnić ramki dla innych stron. Są dwa podejścia do problemu usuwania stron z pamięci. Albo tak skonstruujemy programy, żeby informowały system o sposobie używania przez siebie stron pamięci, albo musimy wyposażyć system w mechanizmy przewidywania zachowania się procesów. Nad pierwszym sposobem jeszcze się pracuje, natomiast drugi – łatwiejszy – doczekał się trzech realizacji: strategia losowa (losujemy stronę do usunięcia), kolejka prosta (odsyłamy na dysk ta stronę, która już najdłużej jest w pamięci) oraz strategia LUR (ang. Least Recently Used – czyli usuwamy stronę ostatnio najmniej używaną. Dwie pierwsze stosuje się ze względu na ich prostotę, mimo że mogą często podejmować złą decyzję. Trzecia myli się rzadziej, ale kosztuje system bardzo dużo czasu, ponieważ musi on uaktualniać całą tablicę stron po każdym odwołaniu się do jednej z nich. W praktyce stosuje się pewne ulepszenia tej metody, np. strategia sprowadzani wstępnego polega na sprowadzaniu stron na zapas, „bo a nuż się mogą przydać”. Natomiast bardzo niepożądanym zjawiskiem w zagadnieniach pamięci wirtualnej jest tzw. migotanie stron, czyli ciągle odsyłanie na dysk (wskutek zastosowania złej strategii) tych stron, które są potrzebne bardzo często. Takie dane nie powinny być w ogóle odsyłane do pamięci pomocniczej.

W teorii systemów operacyjnych przez słowo proces rozumie się program w trakcie wykonywania. Ponieważ program jest sformalizowanym zapisem algorytmu, więc można powiedzieć, że proces jest sekwencją zmian stanu systemu komputerowego, zachodzących zgodnie z tym algorytmem. Zmian tych dokonuje procesor. Procesy mogą być skończone lub nieskończone. Przykładem procesów potencjalnie nieskończonych są wszystkie procesy samego systemu operacyjnego, a także niektóre procesy w systemach czasu rzeczywistego (np. sterowanie robotami na linii produkcyjnej). Jeżeli kilka procesów może być w danej chwili wykonywanych naraz, to mówimy, że wykonują się równolegle, a nie jednocześnie. W języku potocznym gdy mówimy „Oni jednocześnie skoczyli do wody”, to mamy na myśli, że te dwa skoki zdarzyły się w tej samej chwili (tzn. równolegle). Natomiast, kiedy powiemy „On jednocześnie gra na pięciu szachownicach”, mamy na myśli, że on dzieli swój czas miedzy pięć partii szachów”. Ale w danej chwili może grać tylko na jednej szachownicy, tak jak jeden procesor może wykonywać tylko jeden proces. Ta jednoczesność w drugim znaczeniu jest także możliwa do zrealizowania w systemie. Są to tak zwane systemy z podziałem czasu (ang. time sharing systems). W systemach tych (ponieważ są one także wielodostępne – ale np. Windows 95 nie jest) wielu użytkowników ma kontakt z komputerem przez zdalne końcówki – tzw. terminale. Określoną pracę związaną z obróbką danych nazywamy zadaniem (ang. job). System operacyjny przydziela na zasadzie priorytetów, odcinek czasu dla każdego zadania. Odcinek czasu (ang. time slice) stanowi czas przydzielony zadaniu (inaczej też kwant czasu). W każdym określonym kwancie czasu system operacyjny sprawia, że komputer wykonuje zadanie dopóty, dopóki nie zaistnieje jeden z następujących czterech warunków:

  1. zadanie jest zakończone,
  2. wykryto błąd,
  3. trzeba wykonać operację wejścia/wyjścia,
  4. skończył się przydzielony odcinek czasu.

W każdym z tych przypadków procesor przystępuje do wykonywania zadania z kolejnym, najwyższym priorytetem. W pierwszych dwóch przypadkach można usunąć zadanie z pamięci. W dwóch ostatnich zadanie jest wstrzymane tylko chwilowo. Trzeba teraz nieco wzbogacić wcześniejszą definicję procesu. Proces jest to program wykonywany w pamięci operacyjnej przez procesor, ale w ustalonym środowisku i kontrolowany przez system operacyjny. Przez środowisko procesu rozumie się wszystkie informacje systemowe związane z jego wykonaniem, a nie stanowiące jego integralnej części. Proces jest aktywny, jeśli jądro o nim wie (tzn. jego dane istnieją w tablicach systemowych) i zamierza coś z nim zrobić (najchętniej wykonać i mięć go „z głowy”).

Programy mogą mieć – jak już wcześniej wspomniałem – jedną z dwóch postaci: zwykłą lub „wielochodliwą” (ang. re-entrant). Korzyści płynące ze stosowania programów wielochodliwych (czyli typu *.EXE) są wyraźne w systemach wielodostępnych. Wielu użytkowników może tam mieć uruchomiony ten sam program, ale nie trzeba wtedy trzymać kilku jego kopii w pamięci. Segment kodu – który podczas działania programu się nie zmienia – może być dla tych wszystkich procesów wspólny. Rożne muszą być natomiast segmenty danych, stosu oraz środowiska (gdyż każdy użytkownik pracuje z tym programem inaczej).

W systemach jednostanowiskowych – takich jak MS DOS – procesy w systemie mają strukturę liniową. Struktura ta jest najprostsza z możliwych. Proces główny – czyli jądro systemu – uruchamia nieskończony proces powłoki systemowej. Ten z kolei uruchamia inne procesy, a one jeszcze kolejne, itd. Każdy z nich, po uruchomieniu nowego procesu, czeka na jego zakończenie i dopiero potem przejmuje sterowanie na nowo. Proces uruchamiający inny proces, jest procesem macierzystym, a proces uruchamiany jest procesem potomnym. Dany proces może też formalnie zakończyć działanie i pozostać w pamięci jako tzw. program TSR (ang. Terminate and Stay Resident). Praktycznie nie ma potem możliwości usunięcia go, ani ponownego uruchomienia. Musi on przejąć jakieś przerwanie i sam usunąć się z pamięci. Nie jest to doskonały mechanizm i dzisiaj już rzadko stosowany. Dzisiejsze systemy z ochroną pamięci (np. Linux) nie pozwalają także na przejmowanie przerwań, ani na korupcję innych usług systemowych. To jest także elementem ochrony przed wirusami.

W systemie Unix cała sprawa z uruchamianiem procesów komplikuje się, ponieważ generalnie jest to system wieloprocesowy i wielodostępny. Zainicjowanie procesu jest tu także wynikiem działania innego procesu. Po rozpoczęciu pracy z systemem, jądro przydziela danemu użytkownikowi proces programu shell (interpretatora poleceń). Ten z kolei uruchamia inne procesy albo jako pierwszoplanowe (czeka na ich zakończenie), albo jako drugoplanowe (uruchomiony proces „chodzi” w tle, a powłoka systemu działa dalej). Proces macierzysty nie zawsze więc czeka na zakończenie procesu potomnego. Nie musi tego robić, ponieważ i tak wszystkie procesy działają jednocześnie (chyba, że potrzebuje skorzystać z jakichś wyników procesu potomnego i musi – siłą rzeczy – poczekać, aż te wyniki powstaną). Uruchamianie procesów nie tworzy tu struktury liniowej, lecz strukturę drzewiastą. Służy do tego tzw. mechanizm rozwidlenia (ang. fork). Proces macierzysty (tzw. przodek) rozwidla się, czyli zastępuje siebie samego przez dwa identyczne procesy, a następnie jeden z nich zmienia na proces potomny (to zależy od tego, czy powstały proces ma być pierwszo-, czy drugoplanowy). W ten sposób powstaje hierarchia procesów o strukturze drzewa. Podstawową cechą różniącą tę strukturę od liniowej jest to, że wszystkie procesy w systemie są współbieżne. Mówimy, że dwa procesy są współbieżne, jeśli jeden z nich rozpoczyna się przed zakończeniem drugiego. Zgodnie z tą definicją proces nieskończony jest współbieżny ze wszystkimi innymi, które rozpoczęły się później. Współbieżne mogą być także procesy wykonujące się na różnych komputerach (nawet ze sobą nie połączonych). Z tego faktu dalej jednak nic nie wynika, bowiem procesy te nie mają na siebie na ogół żadnego wpływu. Wykonania procesów mogą być jednak od siebie uzależnione – o czym później.

Każdy proces działający w systemie musi zawierać w swoim środowisku takie informacje jak: identyfikator użytkownika, który go uruchomił (inaczej właściciela procesu), identyfikator przodka (procesu macierzystego), identyfikator własny (unikatowa liczba, inna dla każdego procesu w systemie), identyfikator pliku z programem (sam program może należeć do innego użytkownika), prawa procesu w dostępie do rożnych zasobów systemu, adresy części procesu w pamięci oraz aktualny stan procesu (może być tych stanów dużo, a ich przykładowe nazwy w systemie Unix to: tryb użytkownika, tryb jadra, gotowy do wykonania, uśpiony, gotowy w pamięci pomocniczej, uśpiony w pamięci pomocniczej, wracający do trybu użytkownika, nowo utworzony, w stanie zombie). Proces ciągle przechodzi miedzy tymi stanami aż do jego zakończenia. Jeden błąd w przydziale priorytetu albo czasu może być katastrofalny w skutkach dla innych procesów. Dlatego sposób przechodzenia między tymi stanami musi być dokładnie określony.

Wiemy już, że wielozadaniowość w systemach z jednym procesorem jest realizowana przez podział czasu tego procesora na poszczególne zadania. Zarządzanie czasem procesora i przydzielanie go procesom nazywa się szeregowaniem procesów. Czekają one bowiem w pewnej kolejce do procesora. Metodę przydziału procesora do każdego zadania na równe kwanty czasu nazywamy metodą Round Robin. Jednak nie wszystkie procesy zachowują się tak samo. Można zatem wyróżnić procesy obliczeniowe, procesy przetwarzania danych, procesy intensywnie wykorzystujące niektóre zasoby systemu. Uwzględniając charakter procesu można przydzielać mu określone priorytety, a dopiero na ich podstawie określać długość przydzielanego mu kwantu czasu. Na przykład proces edytora potrzebuje prawie natychmiastowej reakcji na polecenia wydawane mu z klawiatury i powinien mieć większy priorytet (wbrew zdrowemu rozsądkowi) niż na przykład proces obliczeniowy, o którym wiadomo, że będzie długo „chodził”. Po upływie przydzielonego procesowi kwantu czasu system wywłaszcza proces (tzn. zabiera mu sterowanie albo inne zasoby poprzez przerwanie zegarowe) i przekazuje sterowanie do kolejnego procesu z kolejki priorytetowej. Wszystko byłoby w porządku, gdyby proces wykonywał tylko jedną czynność. Na nieszczęście dla systemu, a z plusem dla użytkownika – procesy w trakcie wykonywania – mogą dynamicznie zmieniać swój charakter. System musi więc dynamicznie zmieniać im priorytety i długości kwantów czasu. Od czego powinna zależeć ta zmiana? System prowadzi szereg statystycznych obliczeń związanych z aktywnymi procesami. Obliczenia te dotyczą wykorzystania czasu procesora i urządzeń zewnętrznych oraz tzw. czasu bezczynności. Warto na przykład preferować procesy dające zatrudnienie urządzeniom zewnętrznym, gdyż do tego w dalszej pracy nie będzie przez jakiś czas potrzebny główny procesor (na przykład wspomniane już kanały). Oprócz tego system często zmienia priorytety procesom automatycznie (np. co jedną sekundę) aby uniknąć zmonopolizowania dostępu do procesora przez jeden z procesów. Kiedyś było to możliwe przez odpowiednie skonstruowanie procesu i jego praw dostępu. Priorytety procesów są także podzielone na priorytety poziomu jądra i poziomu użytkownika. Priorytety poziomu jądra nie mogą być zmieniane tak jak priorytety procesów na poziomie użytkownika. Jednocześnie jądro nie pozwala, aby jakikolwiek proces uzyskał priorytet jądra. Jest to możliwe tylko, gdy proces jest uśpiony (tzn. aktualnie się nie wykonuje – np. na coś czeka).

Wykonania procesów współbieżnych mogą być także od siebie uzależnione. Uzależnienie takie może wynikać z faktu, że procesy ze sobą współpracują, albo między sobą współzawodniczą. Współpraca wymaga od nich komunikowania się. Skoro są one współbieżne, to muszą ich akcje być jakoś w czasie uporządkowane. Takie porządkowanie procesów w czasie nazywa się synchronizowaniem. Współzawodnictwo procesów też wymaga synchronizacji. Procesy najczęściej współzawodniczą o dostęp do zasobów systemu. Obiekt, z którego może korzystać kilka procesów, w teorii systemów operacyjnych nazywa się zasobem dzielonym, a fragment procesu korzystający z niego nazywamy sekcją krytyczną. Zapewnienie, że co najwyżej jeden proces wykonuje w danym przedziale czasu sekcję krytyczną nazywa się problemem wzajemnego wykluczania. Jak na przykład zapewnić, że gdy jeden program dodaje do pewnego licznika jedynkę, to drugi tego nie robi równolegle? Naturalnie można by na czas korzystania z licznika ustawiać jakiś inny znacznik na 1, a po zakończeniu sekcji krytycznej, ustawić go ponownie na 0. Niestety operacje na takim znaczniku są także sekcją krytyczną. W 1968 roku Holender E. W. Dijkstra zaproponował mechanizm do obsługi wzajemnego wykluczania programów, który nazwał semaforem (na podobieństwo semafora kolejowego, który chroni przed wjechaniem dwóch pociągów na ten sam tor). Semafor to zmienna o wartościach naturalnych, na której można wykonywać tylko dwie operacje: podnoszenie semafora (plus jeden) i opuszczanie (minus jeden). Program wykonujący sekcję krytyczną opuszcza semafor, wstrzymując inne programy, a po zakończeniu sekcji krytycznej znowu go podnosi. W momencie, gdy semafor jest opuszczony, a inny program próbuje go opuścić, jest on wstrzymywany do momentu, aż inny program podniesie ten semafor. Operacje na semaforach są wykonywane za pośrednictwem systemu operacyjnego. Chroni to przed niepowołanym do nich dostępem.

Problemy z przydziałem zwykłych zasobów systemu (pamięć, urządzenia zewnętrzne, dane) wcale nie są prostsze niż z zasobami dzielonymi. System musi podejmować decyzje, kiedy, komu i na jak długo można przydzielić dany zasób . Zagłodzenie procesu następuje wtedy, gdy nie dostaje on potrzebnych mu zasobów na czas (albo w ogóle). Na przykład, gdy proces potrzebuje na raz dostępu do dwóch zasobów, to pozostałe procesy (potrzebujące tylko po jednym z nich) mogą mu je ciągle zabierać, aż zostanie zagłodzony (nie doczeka się na nie). Może też wystąpić tzw. blokada procesów. Zjawisko to dotyczy zawsze pewnej grupy procesów. Każdy proces z tej grupy czeka na zdarzenie, które może być spowodowane tylko przez inny proces. Jest to powszechnie znane na świecie zjawisko i występuje w wielu dziedzinach życia. Za przykład blokady można podać taką sytuację: Ludzie mało zarabiają, bo fabryki nie mogą im więcej zapłacić. Nie mogą im zapłacić, bo nie mogą sprzedać własnych towarów. Nie mogą ich sprzedać, bo ludzie ich nie kupują, gdyż mają za mało pieniędzy. Jest to klasyczny przykład blokady – kryzys gospodarczy. Inaczej można tez nazwać blokadę błędnym kołem. Zjawisko blokady jest bardzo niekorzystne, gdyż hamuje wszystkie działania i tworzy sytuacje bez wyjścia. Pokonać blokadę można tylko przez złamanie wcześniej przyjętych zasad. Są rożne sposoby radzenia sobie z blokadą. Wyróżniamy dwa podejścia do problemu blokady: zapobieganie lub unikanie, albo wykrywanie i usuwanie.

Zapobieganie blokadom polega na takim zaprojektowaniu systemu, aby blokada nie mogła wystąpić. Próba uniknięcia blokady może często powodować zagłodzenie. Jeśli proces oczekuje na zasoby, których w danej chwili nie można mu przydzielić, można zabrać mu te zasoby, które już posiada, ponieważ i tak z nich nie korzysta. Ale w ten sposób może on zostać zagłodzony. Kiedy natomiast wiemy, że blokada ma szansę się pojawić, musimy (nie my, a raczej system) mieć sposób na jej wykrywanie i usuwanie. Najważniejszym problemem jest wówczas wybór procesu-ofiary, któremu odbierze się posiadane zasoby, aby inne procesy mogły działać dalej. Kryterium wyboru takiego procesu może być: liczba i typ posiadanych zasobów, liczba zasobów potrzebnych do zakończenia działania, czas do zakończenia obliczeń lub specjalny priorytet.

Najważniejszym zasobem systemu jest pamięć, ale oprócz niej mamy jeszcze dyski, drukarki, sieć oraz – o dziwo – monitor (np. w okienkowych systemach graficznych, jak Windows wiele programów może jednocześnie zmieniać wygląd swojego okna i nie wolno im zmieniać okna innego procesu). Na dysku zapisuje się różne informacje w postaci tzw. plików. Gdy zlecamy systemowi zapisanie pliku na dysku, nie zastanawiamy się, w którym miejscu tego dysku plik zostanie naprawdę zapisany. Informacja ta jest nam niepotrzebna tak długo, jak system potrafi go odnaleźć. Gdy dysk został w jakiś sposób fizycznie uszkodzony, zaczyna mieć znaczenie, gdzie i w jaki sposób system operacyjny zapisał nasze pliki. Dyski są stworzone po to, by pliki nie tylko zapisywać i odczytywać, ale i kopiować, usuwać, nazywać i zmieniać te nazwy. Jeśli chcemy jak najlepiej wykorzystać pamięć dyskową, powinniśmy zapisywać pliki w wolnych sektorach, bez względu na to, gdzie się one znajdują. W tym przypadku dla każdego sektora pliku, musimy pamiętać, gdzie są jego następne sektory. Taka metoda nazywana jest metodą listową (np. system plików FAT w MS-DOS). Istnieje także tzw. metoda indeksowa, w której oprócz plików, znajdują się na dysku specjalne indeksy. W takim indeksie są wszystkie potrzebne systemowi informacje o pliku, a także szereg informacji dodatkowych. Metoda ta jest zaimplementowana w systemie Unix, gdzie indeks nazywa się i-węzłem i zawiera takie dane jak:

  • numer identyfikacyjny właściciela pliku,
  • prawa dostępu do pliku dla innych użytkowników,
  • numery bloków (grup sektorów dysku) zajętych przez plik,
  • rozmiar pliku,
  • czas ostatniej modyfikacji pliku,
  • czas ostatniej modyfikacji i-węzła,
  • czas ostatniego dostępu do pliku,
  • rodzaj pliku,
  • liczbę dowiązań do pliku.

Pliki nie są przechowywane na dysku po kolei, ale w skomplikowanej strukturze drzewiastej. W katalogu głównym (ang. root directory) mogą znajdować się pliki, a także inne podkatalogi, w których mogą być pliki i podkatalogi, itd. Jest to mechanizm szczególnie przydatny podczas organizowania pracy wielu użytkowników, a także umożliwia tematyczne sortowanie danych zawartych w plikach.

Obecnie dominującą ideą w systemach operacyjnych jest, aby wszelkie operacje wejścia/wyjścia wyglądały tak, jak operacje na plikach. O takich systemach – które to umożliwiają – mówimy, że są niezależne od urządzeń. Niezależność tę osiąga się definiując fikcyjne, wirtualne urządzenie, które funkcjonalnie odpowiada na przykład dyskowi. Oczywiście żadne prawdziwe urządzenie nie ma wszystkich cech takiego urządzenia wirtualnego. Podprogramy obsługi urządzeń (sterowniki) tworzy się właśnie po to, aby niejako tłumaczyły zadania kierowane do urządzenia wirtualnego, na dostępne operacje urządzenia fizycznego. W ten sposób programy użytkownika mogą komunikować się nawet z nieznanym urządzeniem, jeśli tylko zainstalowaliśmy w systemie dla niego odpowiedni sterownik. Urządzenia traktuje się jak tzw. pliki specjalne. Istnieją dwa rodzaje plików specjalnych (czyli urządzeń wejścia/wyjścia): blokowe i znakowe. Dla urządzeń blokowych (np. dyski, sieć) stosuje się buforowanie danych. Zadanie zapisu danych na dysk, jest przez system interpretowane, jako zapis do bufora. Dopiero wtedy, gdy system ma trochę „wolnego czasu” zapisuje bufory na dysk (chyba, że zażądamy natychmiastowego wyczyszczenia buforów – tzw. operacja flush). Operacje wejścia/wyjścia związane z urządzeniami znakowymi przebiegają następująco: sterownik tego urządzenia zajmuje się tylko pojedynczymi znakami; dla znaków o specjalnym znaczeniu wykonuje odpowiednie akcje, a pozostałe znaki przekazuje dalej. Urządzenia znakowe mogą działać na zasadzie tak zwanego strumienia. Strumień – tak jak w rzeczywistości – to urządzenie, z którego można korzystać tylko w sposób liniowy i – tak jak nie można dwa razy wejść do tej samej rzeki (strumienia) – nie można już odczytać, ani zmienić znaków już raz wysłanych do strumienia. Strumieniem może być klawiatura, monitor, plik, jeden z portów, a nawet drukarka. Każdy proces uruchomiony w systemie ma standardowo przypisane kilka strumieni:

  • strumień wejściowy (klawiatura),
  • strumień wyjściowy (ekran monitora),
  • strumień diagnostyczny (ekran monitora),
  • strumień dodatkowy (złącze szeregowe COM1),
  • strumień drukarki (najczęściej złącze równoległe LPT1).

Jeśli dany program jest tak skonstruowany, że korzysta ze standardowych strumieni wejścia/wyjścia, to można łatwo skierować jego wyniki do innego strumienia (np. zamiast na ekran – do pliku). Można tez skierować wyjście jednego programu na wejście innego i utworzyć w ten sposób tzw. łącze (ang. pipe – dosłownie rura). Na przykład w DOS-ie można wydawać interpretatorowi polecenia takie jak:

dir c:\ /s /b | find „LOG” > loglist.txt

Pozwalając na jednoczesne wykonywanie wielu programów różnych użytkowników należało także wymyślić pewne formy zabezpieczenia. System operacyjny musi wiedzieć, z jakimi użytkownikami ma aktualnie do czynienia i na co może im pozwolić. Jeśli dany użytkownik chce rozpocząć pracę z systemem, musi podać swój identyfikator oraz hasło. System tworzy dla niego tzw. sesję, uruchamiając proces interpretatora przyjmujący polecenia od użytkownika. Specjalne polecenie interpretatora kończy daną sesję (np:. logout, exit, bye, arrivederci, itp). Dopiero wtedy można rozpocząć nową sesję z systemem.

W instytucjach, w których wiele osób wspólnie korzysta z komputerów, instaluje się tzw. lokalne sieci komputerowe. Sieć łącząca komputery działa w podobny sposób, jak sieć telefoniczna czy telegraficzna. Z punktu widzenia pojedynczego komputera połączenie z siecią jest jednym z urządzeń wejścia/wyjścia. System operacyjny pojedynczej stacji roboczej (bo tak się nazywa samodzielny komputer w sieci) nie może sam zarządzać połączeniem z siecią. Przesłanie komunikatu przez sieć do innego komputera wymaga także pewnych akcji ze strony odbiorcy. System operacyjny, który działa na komputerach połączonych siecią i dbający o prawidłowy przepływ danych miedzy nimi nazywamy sieciowym systemem operacyjnym (ang. Network Operating System). Przykłady to Novell NetWare, Unix i Windows NT. Podstawowe zadania, jakie dzisiaj stoją przed systemem sieciowym to:

  1. przesyłanie miedzy stacjami danych, plików i komunikatów,
  2. udostępnianie usług poczty elektronicznej (e-mail),
  3. sieciowe usługi katalogowe (np. Active Directory),
  4. bezpieczeństwo dostępu do programów i danych,
  5. archiwizację danych i ich kopie zapasowe,
  6. zarządzanie grupami użytkowników,
  7. możliwość współpracy z Internetem.

System taki musi przede wszystkim dbać o niezawodność komunikacji w sieci lokalnej (tzw. Intranecie). Najlepiej, jeśli jeden z komputerów jest wyróżniony spośród pozostałych i to on sprawuje kontrolę nad transmisją danych w sieci. Taki komputer nazywamy serwerem. Pełni on także role udostępniającego rożne usługi systemowe i to za jego pomocą odwołujemy się do zasobów systemu, głownie do dysków i drukarek. Użytkownicy w systemie sieciowym posiadają specjalne konta, które określają ich prawa dostępu do zasobów systemu, zapewniają bezpieczeństwo danych, specyfikują skrypty logowania, katalog roboczy użytkownika oraz określają jego przynależność do rożnych grup. Grupę taka mogą stanowić np. studenci jednego roku, pracownicy firmy pracujący nad tym samym projektem, albo osoby często grające w jedna grę. Najważniejszym powodem tworzenia grup jest ułatwienie w nadawaniu użytkownikom praw dostępu. Użytkownikom należącym do tej samej grupy często nadaje się te same prawa dostępu (np. pewien wspólny obszar na dysku). W sieci lokalnej mogą być stacje z własnym dyskiem, oraz stacje bezdyskowe. Systemy sieciowe są tak projektowane, aby każdy z użytkowników miał zwykle dostęp do większego obszaru pamięci dyskowej, niż tylko posiadany przez stację, na której pracuje. Stacja nie posiadająca własnego dysku twardego powinna mieć dostęp do innych dysków w sieci. System operacyjny powinien umieć ukryć przed programami fakt nie posiadania własnego dysku. Jeśli dostęp do plików zdalnych (tzn. nie znajdujących się w lokalnej strukturze katalogów) odbywa się tak, że program użytkowy nie wie nic o przekraczaniu granic komputerów. Tę cechę systemu plików nazywamy przezroczystością. Jest to pojecie odnoszące się także do innych zasobów systemu (pamięci, drukarek, procesorów). Gdybyśmy mogli zlecać nasze zadania nie jakiemuś określonemu komputerowi, ale sieci komputerów jako całości, to system operacyjny, który to umożliwia nazwalibyśmy rozproszonym systemem operacyjnym. System taki musi pełnić jeszcze więcej funkcji, niż zwykły sieciowy system operacyjny. Tu nie wystarczy samo nadzorowanie przepływu informacji. System rozproszony, pracując równolegle (a nie tylko jednocześnie) na wielu połączonych komputerach, stwarza użytkownikowi wrażenie, że ma on do czynienia z jednym olbrzymim komputerem, którego zasoby są suma zasobów wszystkich komputerów w sieci. Systemy rozproszone muszą obsługiwać na raz całą sieć komputerów. Jest to niezwykle trudne zadanie ze względu na różnorodność sieci i stacji roboczych się w nich znajdujących. W sieci może być na przykład 10 komputerów. Trzy z nich maja po dwa procesory, a siedem – po jednym; 5 komputerów ma dyski, ale każdy innej firmy; dwa komputery to Macintoshe, siedem to IBM PC, a jeden jest stacją roboczą Silicon Graphics, itd. System rozproszony musi być wielozadaniowy i wieloprocesorowy. Musi też – siłą rzeczy – obsługiwać sieci komputerowe. Podstawowym zadaniem takiego systemu jest równoległe przetwarzanie procesów i równoważenie obciążenia poszczególnych procesorów i komputerów.

Istnieją dwie architektury wieloprocesorowe: silnie sprzężone (procesory komunikują się poprzez wspólną pamięć) i luźno sprzężone (komunikacja przez magistralę). Systemy operacyjne dla tych architektur nazywa się współbieżnymi systemami operacyjnymi (ang. parallel operating systems). Przykładem może być system Tunis oparty na Unix-ie. Odróżnia się te systemy od rozproszonych systemów operacyjnych, które działają na architekturze wielomaszynowej. Przykłady systemów rozproszonych to Mach i Chorus (także oparte na Unix-ie). Na superkomputerach takich jak Cray działają wersje Unix-a, jednocześnie współbieżne i rozproszone. Należy zwrócić uwagę, że rozproszenie nie jest synonimem przetwarzania współbieżnego, ale oznacza przekazywanie przetwarzania do komputerów najlepiej się do tego nadających.

Środowisko rozproszone daje nowe możliwości działania programów, które już dziś korzystają z pewnych rozproszonych metod przetwarzania informacji (tzw. aplikacje rozproszone). Komunikacja miedzy aplikacjami przyjmowała kolejno następujące formy:

  1. wymiana – aplikacje z różnych komputerów przesyłają pomiędzy sobą zwykle pliki,
  2. dzielenie zasobów – zasoby są bezpośrednio dostępne dla wielu aplikacji na różnych komputerów,
  3. współpraca – aplikacje z różnych komputerów uzupełniają się wzajemnie przy realizacji danego zadania.

Przetwarzanie rozproszone ma na celu dalszą optymalizację wykorzystania zasobów i uproszczenie pracy użytkownika (co zwykle oznacza komplikację pracy programisty). Termin zasoby jest tu o wiele szerszym pojęciem, niż dotychczas. Procesy mogą bowiem dzielić się mocą obliczeniową, pojemnością pamięci, a nawet wydajnością grafiki 2D/3D i innymi „nowymi” możliwościami komputerów. Dużą rolę w teorii aplikacji rozproszonych zajmuje przezroczystość (tzn. dla użytkownika nieistotna jest fizyczna lokalizacja zasobów – ale np. drukować chcemy „u siebie”, a nie gdzieś w oddziale w Chinach) oraz model klient-serwer (jeden proces (klient) żąda od drugiego (serwera) wykonania pewnej usługi, przy czym mogą to być procesy zdalne lub lokalne).

Aplikacje rozproszone pozwalają na:

  • zwiększenie wydajności dzięki umożliwieniu obróbki danych przez komputery najlepiej się do tego nadające,
  • uzyskanie nowych możliwości, wynikające ze zwiększenia wydajności,
  • zwiększenie wygody użytkownika; nie musi on znać rożnych systemów i zajmować się przesyłaniem plików pomiędzy nimi.

Mają także swoje słabe punkty:

  • zależność od dostępności i wydajności sieci (aplikacja nie może działać, gdy sieć jest uszkodzona; jeśli sieć jest bardzo obciążona, jej wydajność spada i czas komunikacji rośnie),
  • problemy bezpieczeństwa (używając wielu komputerów zwiększa się ryzyko, gdyż bezpieczeństwo zależy zawsze od najmniej zabezpieczonego komputera w sieci).

Ale za to jakie zalety:

  • dostępność i optymalizacja wykorzystania zasobów (jest to głównym powodem istnienia aplikacji rozproszonych,
  • nowe możliwości i zwiększenie wydajności aplikacji,
  • elastyczność i dostępność (w wypadku awarii jednego komputera można spróbować od razu zastąpić go przez inny).

Do systemów rozproszonych niewątpliwie należy przyszłość. Fakt, że istnieją już specjalne algorytmy rozproszone (tzn. takie, że suma pojedynczych lokalnych działań daje globalne efekty przetwarzania) może zwiastować szybki postęp w tej dziedzinie.

Kilka lat temu praca z komputerem polegała na wpisywaniu z klawiatury poleceń i oczekiwaniu na wyświetlenie wyniku. Wszystko odbywało się w trybie znakowym i o jakiejkolwiek grafice nie było nawet mowy. Przykładem może być MS DOS firmy Microsoft. Wprawdzie powstało wiele programów dla tego systemu, które posiadały grafikę, jednak najczęściej uzyskiwana ona była poprzez bezpośrednie odwołania do BIOS-u. Sam MS DOS nie oferował i do tej pory nie oferuje mechanizmów graficznych. Na szczęście nie trzeba się dzisiaj zajmować szczegółami formatu plików, sposobem przydziału pamięci oraz wykonywaniem programów. Tym wszystkim automatycznie zajmuje się system operacyjny. Skrót nazwy najpopularniejszego systemu operacyjnego MS-DOS pochodzi od Microsoft Disk Operating System. System CP/M-80 (skrót od Control Program for Microcomputers) na komputer Amstrad/Schneider CPC 6128 był bezpośrednim przodkiem DOS-a. Jego wersja dla komputerów ELWRO Junior 801 – CP/J była swego czasu bardzo powszechnie w Polsce stosowana. Następnie pojawił się system IBM DOS (pliki systemowe miały wtedy nazwy IBMBIO.COM oraz IBMDOS.COM). System MS-DOS „normalnie” obsługuje tylko pamięć zwykłą. Można zainstalować odpowiednie sterowniki pamięci rozszerzonej, jak: HIMEM.SYS, QEMM.EXE, EMM386.EXE, RAMDRIVE.SYS, SMARTDRV.SYS – które umożliwiają użycie całej pamięci do rożnych celów, ale tylko programom zgodnym z tymi sterownikami. System MS-DOS można konfigurować przy pomocy specjalnego pliku o nazwie CONFIG.SYS. Odczytywany jest on przy każdym ładowaniu się systemu i ustawia odpowiednio różne opcje, przydziela pamięć na bufory dysków oraz instaluje sterowniki urządzeń. Przykładowy plik CONFIG.SYS może wyglądać tak:

DEVICE=C:\DOS\HIMEM.SYS ; pamięć wysoka HMA i XMA
DEVICE=C:\DOS\EMM386.EXE NOEMS ; pamięć danych stronicowana na zadanie
DOS=HIGH,UMB ; system w pamięci wysokiej i używanie bloków UMB
BUFFERS=50,8 ; bufory dla operacji dyskowych
BREAK=OFF ; wyłączenie działania kombinacji klawiszy CTRL-BREAK
FILES=60 ; maksymalna liczba otwartych na raz plików
STACKS=9,256 ; rozmiar stosu systemowego
FCBS=4,0 ; liczba bloków FCB (stary mechanizm plików z systemu CP/M)
LASTDRIVE=J ; ostatnia możliwa litera dysku
DEVICEHIGH=C:\DOS\SMARTDRV.SYS 1024 ; bufory dysku
DEVICEHIGH=C:\DOS\DRVSPACE.SYS /MOVE ; kompresja dysku w tle
DEVICEHIGH=C:\DOS\DISPLAY.SYS CON=(ega,437,2) ; wyświetlanie stron
DEVICE=MOUSE.SYS ; sterownik myszy
COUNTRY=048,852,C:\DOS\COUNTRY.SYS ; określenie informacji o kraju
SHELL=C:\DOS\COMMAND.COM C:\DOS\ /p /e:2048 ; powłoka systemu

Obecnie na rynku dostępny jest MS DOS w wersji 6.22. Istnieją również konkurencyjne systemy (tzw. systemy dosopodobne) wywodzące się z MS DOS i w pełni z nim zgodne:

  • PC DOS 7.0 firmy IBM,
  • Novell DOS 7.0,
  • PTS DOS rosyjskiej firmy PhysTechSoft,
  • DR DOS firmy Digital Research,
  • itd…

Każdy z nich ma swoje wady oraz zalety i mimo to, że produkt firmy Microsoft był pierwowzorem i zdobył największą popularność, to wydaje się być najmniej zaawansowany technologicznie (np. Novell i PTS oferują mechanizmy sieciowe).

Ogólnie przyjęło się jednak przeświadczenie, że DOS zostanie wyparty przez system graficzny. Pewnym tego przedsmakiem jest środowisko Windows 3.x firmy Microsoft. Nie jest to na razie samodzielny system operacyjny, a jedynie specyficzna „nakładka” oferująca mechanizmy graficzne oraz własne biblioteki programistyczne Windows API (Application Programing Interface). O tym czy był to własny pomysł firmy Microsoft można by się długo spierać, zwłaszcza dlatego że graficzne systemy „okienkowe” istniały już w czasach DOS-u na komputerach Macintosh firmy Apple. Dzięki graficznemu interfejsowi programistycznemu wszystkie programy pracujące w tym środowisku wyglądają podobnie i podobnie się zachowują. Windows w wersji 3.0, a następnie ulepszone jako 3.1, odniosły ogromny sukces na rynku i zrewolucjonizowały sposób pracy z komputerem klasy PC.

Najmłodszym dzieckiem z linii 3.x są Windows for Workgroups 3.11. Zostały one przede wszystkim wyposażone w mechanizmy sieciowe, jak również w niektóre 32-bitowe podsystemy (np. obsługa dysków, plików i sieci). Firma Microsoft zaleca stosowanie tego systemu również na pojedynczych komputerach, gdyż posiadają one pewne ulepszenia w stosunku do wersji 3.1. Wspomniane dotychczas systemy są 16-bitowe i można uruchamiać je na słabszych komputerach. Oczywiście w przypadku Windows, oraz każdego systemu graficznego, im lepszy komputer, tym bardziej komfortowa praca.

W sierpniu 1995 roku obyła się premiera systemu Windows 95, tym razem w pełni 32-bitowego systemu. W porównaniu z Windows 3.x rożni się tym, że ma już wbudowany DOS (MS DOS 7.0), jest systemem wielozadaniowym i wielowątkowym, oferuje pełną obsługę sieci, jest łatwiejszy w użyciu oraz zgodny z technologią Plug & Play (czyli podłącz i działaj!), umożliwiającą automatyczne rozpoznawanie i konfigurowanie podłączonych do systemu urządzeń zewnętrznych oraz kart rozszerzeń.

Windows NT jest już potężnym systemem sieciowym, przeznaczonym dla firm, przedsiębiorstw i korporacji. Posiada dwie wersje: Serwer oraz Workstation. Pierwsza pełni rolę serwera sieciowego (serwera plików, dysków, wydruku), natomiast druga jest końcówką roboczą. Windows NT (NT – ang. New Technology) jest w pełni 32-bitowe, posiada zaawansowane mechanizmy bezpieczeństwa oraz dostępne jest na różne platformy sprzętowe, także wieloprocesorowe (np. Intel, PowerPC, DEC Alpha).

Najgroźniejszym konkurentem dla Windows 3.x oraz 95 jest OS/2 Warp firmy IBM. Ten także 32-bitowy graficzny system operacyjny jest wielozadaniowy i wielowątkowy, posiada mechanizmy sieciowe, a także pozwala na uruchamianie aplikacji napisanych dla DOS oraz Windows! Dyskusje na temat wyższości produktu firmy IBM nad Windows są bardzo zażarte. Widziałem go w akcji i byłem naprawdę pod wrażeniem.

Chciałbym jeszcze wspomnieć o systemie Linux. Jego podstawową zaletą jest zgodność z Unixem (co z tego mamy, wiedzą na razie głównie studenci oraz naukowcy), a także to, że jest to program freeware (rozprowadzany za darmo). Jest to system znakowy i raczej trudny do opanowania, aczkolwiek bardzo stabilny i nadający się do profesjonalnych zastosowań.

Oczywiście istnieją jeszcze inne systemy, jak QNX (system czasu rzeczywistego), SCO Unix czy Solaris (przeniesiony na PC system komputerów firmy Sun Microsystems). Są one jednak rzadko stosowane, a z pewnością już nie do zastosowań domowych.

Który system dla kogo? „Goły” DOS dla szczęśliwych posiadaczy komputerów klasy XT lub AT; Windows 3.11 dla tych, którzy pracują na 386 lub nie mogą sobie pozwolić na 8 MB pamięci RAM, jak również dla tych, którzy zbytnio przyzwyczaili się do „starych okienek”, aby przechodzić na Windows 95; Windows 95 oraz nowy na rynku Windows 98 może mieć zastosowanie zarówno w domu, jak i w biurze, pod warunkiem, że mamy odpowiedni sprzęt; OS/2 Warp powinien skusić wszystkich wrogów Windows oraz tych, którzy lubią „grzebać” i nade wszystko cenią stabilność i pełną 32-bitowość; Windows NT jest rozwiązaniem dla firm i przedsiębiorstw; natomiast Linux to tania alternatywa dla zwolenników systemów uniksopodobnych. Warto zaznaczyć, że Windows 3.1, Windows for Workgroups 3.11, Windows 95/98, Windows NT 4.0 oraz OS/2 Warp 4.0 posiadają wszystkie polskie wersje językowe.

Technologia produkcji komputerów nie stanęła oczywiście w miejscu. Inżynierowie stale pracują nad coraz pojemniejszymi pamięciami, coraz szybszymi procesorami i łączami komunikacyjnymi. Być może już niedługo jakiś przełom w tej dziedzinie sprawi, że powstaną nowe możliwości integracji systemów komputerowych, co spowoduje kolejny etap w rozwoju systemów operacyjnych. Ale nie spodziewam się, aby omówione przeze mnie problemy i ich realizacje szybko się zdezaktualizowały. Zbyt wiele pracy włożono w tworzenie istniejącego oprogramowania, by teraz dokonywać gwałtownych zmian. Nowe systemy będą niestety zawsze musiały uwzględniać istnienie starszych rozwiązań.

Źródła:

  1. System operacyjny Unix (Peter P. Silvester) WNT 1991
  2. Windows NT – struktura i użytkowanie (Tom Sheldon) Robomatic 1994
  3. Magazyn Komputerowy ENTER 11/95
  4. PC Magazine po polsku 10/95
  5. Komputery jak ludzie – łagodne wprowadzenie do systemów operacyjnych (Zbigniew Weiss) WNT 1996
  6. Jak działa komputer (Ron White) PWN 1994
  7. Budowa systemu operacyjnego Unix (Maurice j. Bach) WNT 1995
  8. Przetwarzanie rozproszone w systemie Unix (Michael Gabassi, Bertrand Dupouy) Lupus 1995
  9. Jak pisać wirusy? (Andrzej Dudek) ReadMe 1994
  10. Architektura komputerów (M. Morris Mano) WNT 1980

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *