UNIX, Linux jądro - kurs

W tym post-cie, opiszę teoretycznie jądo systemu UNIX.
Jest to czwarta część na moim blogu dotycząca teorii systemów operacyjnych.
W kolejnych częściach opiszę: funkcje systemowe związane z procesami na bazie UNIX-a.
W części pierwszej opisałem: wstęp do UNIX-a.
W części drugiej opisałem: system plików UNIX-a.
W części trzeciej opisałem: powłokę UNIX-a.

Uwaga - materiał pochodzi z mojej skarbnicy wiedzy zgromadzonej podczas studiów na UAM w Poznaniu na przełomie lata 1999-2002 i wtedy też był redagowany. Stanowi doskonałe teoretyczne uzupełnienie wiedzy dla studentów kierunku informatyka.

Proszę traktować tego posta, jako opis jądra systemu operacyjnego UNIX bez podziału na wersje i rodzaje. Tam gdzie jest potrzeba wyraźnie zaznaczam jakiej wersji i jakiego rodzaju systemu operacyjnego UNIX-a dotyczy opis.


Materiał bazuje na książkach:
1. Podstawy systemów operacyjnych - wydawnictwo WNT, autorzy: Abraham Silberschatz i Peter B. Galvin
2. System operacyjny UNIX dla początkujących i zaawansowanych - wydawnictwo BUM, autorzy: Zbyszko Królikowski i Michał Sajkowski

Według mnie najlepsza książka dla osób rozpoczynajacych przygodę z systemem operacyjnym UNIX zarówno pod względem praktycznym jak i teoretycznym dla administratorów i programistów.



Jądro jest najgłębszą częścią systemu operacyjnego UNIX. Działanie systemu operacyjnego w obrębie jądra dzielimy na: - obsługę funkcji systemowych, pułapek i przerwań. W jądrze możemy wyróżnić dwie części: jedna z nich obsługuje zastosowania, a druga przerwania. Struktura jądra - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 95.]

Obie części jądra współpracują w rozdziale zasobów systemu oraz realizacji operacji I/O. Część obsługująca zastosowania rozpoczyna operacje I/O. Rezygnuje z procesora i następnie czeka na powiadomienie przez drugą część, że obsługa I/O została zakończona.
Funkcje systemowe, pułapki i przerwania. Jednym z działań najczęściej wykonywanych w jądrze jest żądanie wykonania funkcji systemowej. Funkcje systemowe zapewniają dostęp do usług świadczących przez jądro, a żądanie ich wykonania można uważać za polecenia dla jądra. Program obsługujący wywołania funkcji systemowej, zanim funkcja systemowa zostanie zainicjowana wykonuje następujące działania wstępne: - odczytuje parametry funkcji systemowej, - sprawdza czy parametry są umieszczone pod poprawnymi adresami i następnie kopiuje je z procesu użytkownika do jądra, - wywołuje w jądrze odpowiedni program obsługujący f. systemową. Wyniki działania funkcji systemowej są zwracane do procesu użytkownika. W przypadku sukcesu program obsługi funkcji systemowej w jądrze zwraca wartość specyficzną dla danej funkcji, w przypadku porażki - wartość -1. W czasie wykonywania funkcji systemowych mogą wystąpić dwa zdarzenia. Do procesu może być wysłany sygnał albo inny proces może osiągnąć wyższy priorytet. Jeżeli do procesu zostanie wysłany sygnał, to może on spowodować zaniechanie funkcji systemowej. Inna możliwość to zawieszenie sygnału do czasu zakończenia funkcji. Jeżeli w systemie istnieje proces o wyższym priorytecie, to program korygujący wywołuje program szeregujący procesy, czyli program obsługujący przydział procesora do procesów. Program ten spowoduje, że procesor zostanie przydzielony do procesu o wyższym priorytecie. Pułapki mogą występować z powodu błędu w programach (na przykład dzielenie przez zero), czy też błędów systemowych (na przykład błąd strony). Proces jest informowany o powstałym problemie albo za pomocą sygnału, albo przez sam fakt swojego zakończenia. Przerwania spowodowane przez urządzenia wejścia/wyjścia są obsługiwane przez moduły obsługi urządzeń (device drivers). Moduły te są włączane do jądra podczas instalacji lub rozbudowy systemu. Programy spowodowane przez inne urządzenia są obsługiwane przez programy przerwań stanowiące standardową część jądra. Przerwania spowodowane przez urządzenia występują asynchronicznie. Programy obsługi urządzeń są uruchamiane na żądanie. Kiedy występuje przerwanie moduł obsługi urządzenia odwołuje się do tzw. stosu przerwań, znajdującego się w części stosu - jądra danego procesu. Program obsługi przerwań musi być wykonany do końca, to znaczy jego wykonanie nie może być przerwane.
Zarządzanie procesami - w systemie UNIX rozróżniamy dwa typy procesów: jądra i użytkowe. Procesy jądra funkcjonują tylko całkowicie wewnątrz jądra. Procesy użytkowe to wszystkie pozostałe procesy, tzn. utworzony przez proces systemowy init i wszystkie procesy z niego wyprowadzane. Proces init wykonuje funkcje administracyjne w systemie, obejmuje obsługę prawidłowego przejścia systemu z trybu jednego użytkownika do trybu wielodostępnego i utworzenie procesu rejestracji (getty) użytkowników. Przejście do trybu wielodostępnego odbywa się zgodnie ze skryptem /etc./rc i obejmuje następujące czynności: - usunięcie plików tymczasowych, ustawienie daty, sprawdzenie systemu plików oraz zainicjowanie programów szeregujących operacje wydruku, a także programów prowadzących księgowości systemu i regulowanie zapisywania bloków buforowanych wewnętrznie przez system na dysk. Podstawą uruchomienia procesu w systemie jest umieszczenie go w pamięci operacyjnej oraz przydzielenie mu procesora. Unix, tak jak każdy system wielozadaniowy stwarza iluzję współbieżnie wykonywania wielu procesów. Jądro systemu określa porządek przydziału zasobów do procesów gotowych do wykonania - mówi o szeregowaniu zasobów systemu. Jądro wykonuje również szeregowanie procesów, tzn. dokonuje ustalenia kolejności, w jakiej procesor ma być przydzielony do procesów gotowych do wykonania. System UNIX wykorzystuje algorytm Round Robin do szeregowania procesów, jednak kwant czasu jest dużo mniejszy niż w standardowej wersji tego algorytmu. Każdy proces ma określony priorytet, przy czym obowiązuje zasada: im większa liczba, tym niższy priorytet. Procesy systemowe wykonujące operacje wejścia/wyjścia oraz inne ważne zadania systemowe mają priorytety o wartościach ujemnych i nie mogą być usunięte przez sygnały. Zwyczajne procesy użytkowników mają priorytety dodatnie, tak więc nie mogą być wykonywane przed systemowymi. Stosowany w systemie UNIX algorytm szeregowania to wielokolejkowy algorytm priorytetowy. Algorytm szeregowania w systemie UNIX - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 98.]

Im więcej czasu procesora dany proces zużywa, tym niższy staje się jego priorytet. We współczesnych systemach kwant czasu procesora przydzielany procesowi to najczęściej 0,1 sekundy (4.3 BSD UNIX), natomiast co sekundę system przelicza na nowo wartość priorytetów, według następującej reguły: nowy priorytet = wartość bazowa + wykorzystanie procesora. Licznik wykorzystania procesora jest zwiększany o 1 z każdym taktem zegara systemowego i jest przechowywany w tak zwanej tablicy procesu. Przekroczenie określonej wartości powoduje przesunięcie procesu do kolejki o niższym priorytecie. Wartość bazowa jest zazwyczaj równa zero. Użytkownik, który pragnie obniżyć priorytet swoich procesów, może ę wartość zwiększyć wykonując funkcje systemową nice. Tylko administrator systemu może obniżyć wartość bazową zwiększając tym samym priorytet swoich procesów. W ramach określonej kolejki do szeregowania procesów jest wykorzystywany algorytm Round Robin. Współpracuje on z systemową procedurą timeout, która przekazuje modułowi obsługi przerwań zegara informację o tym, że upłynął określony kwant czasu. Odpowiednia procedura jądra dokonuje przeszeregowania procesów. Proces traci przydział procesora, gdy skończy się kwant czasu lub gdy oczekuje na zakończenie operacji I/O. Proces może również zrezygnować z przydziału procesora w efekcie zajścia określonego zdarzenia (event). Każdy użytkownik jest identyfikowany przez liczbę całkowitą zwaną identyfikatorem użytkownika (user identification (uid)). Identyfikator przydzielony jest użytkownikowi przez administratora systemu i może znaleźć go w wierszu odpowiadającym nazwie danego użytkownika w pliku /etc./passwd. Każdy proces ma automatycznie przydzielony identyfikator użytkownika który go utworzył. Użytkownik z identyfikatorem równym zero jest użytkownikiem specjalnym zwanym użytkownikiem nadrzędnym (root user albo superuser) albo administratorem systemu. Może on odczytywać i zapisywać wszystkie pliki w systemie, niezależnie od ich właściciela i ich zabezpieczenia. Procesy z identyfikatorem uid równym zero mają możliwość wykonania niewielkiej liczby chronionych funkcji systemowych niedostępnych dla zwykłych użytkowników. Niektóre programy realizujące określone polecenia powinny być dostępne nie tylko administratorowi, ale również zwykłym użytkownikom systemu. Ponieważ ze względu na wymogi bezpieczeństwa systemu, administrator nie może udostępniać hasła do sytemu innym użytkownikom, wprowadzono mechanizm umożliwiający te programy. Mechanizm ten polega na zastąpieniu niektórych bitów określających prawa dostępu do pliku zawierającego program realizujący dane polecenie przez tak zwane bity SETUID. Bity te oznaczone przez s, zastępują wybrane bity x zezwalające na wykonanie programu, a ich obecność oznacza, że efektywnym identyfikatorem użytkownika danego procesu nie jest identyfikator użytkownika który ten proces uruchomił, ale id. użytkownika który jest właścicielem pliku zawierającego wykonywany program. W ten sposób administrator systemu umożliwia w kontrolowany sposób dostęp zwykłym użytkownikom do pewnych informacji o systemie.
Każdy proces dysponuje wydzielonym obszarem pamięci, w którym zawarta jest jego wirtualna przestrzeń adresowa oraz obszary pomocnicze, z których korzysta jądro do zarządzania pracą procesów. W wirtualnej przestrzeni adresowej procesu wyróżnia się cztery segmenty: - segment tekstu programu, - segment danych, - segment stosu, - szczelinę. Segment tekstu programu rozpoczyna się od adresu 0 w wirtualnej przestrzeni adresowej. W segmencie tym nie można niczego zapisywać, można go tylko odczytać. Jest to dzielony między różne procesy wykonujące ten sam kod. W drugim segmencie znajdującym się za tekstem programu, mieszczą się dane użytkownika. W tym obszarze proces może je zarówno zapisywać, jak i odczytywać. W trzecim segmencie pamięci przechowuje się stos. Rozpoczyna się od największego adresu w pamięci wirtualnej procesu. Jeśli stos próbuje przekroczyć granicę segmentu stosu, pojawia się przerwanie sprzętowe. Odpowiednie procedury jądra systemu powiększają rozmiar segmentu stosu  obniżając jego granicę o kilka tysięcy bajtów (najczęściej o rozmiar strony). Programy nie mają możliwości zmiany rozmiaru segmentu stosu. Gdy program rozpoczyna pracę na stos są wpisywane zmienne charakteryzujące środowisko pracy programu oraz samo polecenie i jego argumenty. Obraz procesu w pamięci operacyjnej - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 100.]

Zazwyczaj segment danych i stosu danego programu współdzielą tę samą przestrzeń adresową, lecz rozrastają się niezależnie w przeciwnych kierunkach. Pomiędzy nimi znajduje się obszar nie wykorzystanej przestrzeni, tzw. szczelina. Segment stosu rozrasta się automatycznie, natomiast "ekspansja" segmentu danych jest wykonana z wykorzystaniem funkcji systemowej brk. Jeśli kilku użytkowników wykorzystuje w danej chwili ten sam program, to w pamięci operacyjnej jest przechowywana tylko jedna kopia programu, a nie kilka (po jednej dla każdego użytkownika), jak to się zdarza w innych systemach. Jest to możliwe dzięki mechanizmowi współdzielonego segmentu tekstu programu. Wirtualna przestrzeń adresowa procesów i pamięć fizyczna - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 101.]

Nad wirtualną przestrzenią adresową procesu znajduje się tzw. obszar użytkownika, zawierający informację o stanie procesu. Są to unikalne identyfikatory związane z procesem, informacje o prawach i przywilejach związanych z procesem, obszar ten zawiera również wszystkie deskryptory związane z procesem. Obszar ten może czasami być podzielony na: - strukturę użytkownika która przechowuje informacje o procesie potrzebna tylko wtedy, gdy znajduje się on w p.o. Przechowywany jest tutaj identyfikator użytkownika, który uruchomił proces oraz identyfikator jego grupy. Pamiętany jest tutaj również katalog bieżący i tablica otwartych plików procesu. - blok kontrolny. Informację o procesie dopełniają wektory środowiskowe i argumenty procesu, zawierające wartości parametrów funkcji systemowych i wartości zwracane przez te funkcje. Ogólnie procesy są wykonywane w dwóch trybach: jądra i użytkownika. Wspomniane procesy jądra są wykonywane tylko w trybie jądra natomiast procesy użytkownika mogą być wykonywane w trybie użytkownika i w trybie jądra. Procesy użytkownika mają dostęp do większości usług jądra za pomocą funkcji systemowych. Wywołanie przez proces użytkownika funkcji systemowej powoduje uruchomienie procesu systemowego lub inaczej procesu jądra, który obsługuje wykonanie tej funkcji. Proces jądra wykorzystuje stos różny od stosu procesu użytkownika. Stos jądra (kernel stack) znajduje się zaraz za strukturą użytkownika. Stos jądra i struktura użytkownika tworzą razem systemowy segment danych. Do zarządzania procesami jądro wykorzystuje różnego rodzaju bloki kontrolne. Kiedy proces wykonywany w trybie użytkownika żąda zasobów od systemu operacyjnego za pomocą funkcji systemowej, to następuje zamiana jego trybu na tryb jądra. Każdy tryb pracy wymaga dostępu do różnych zasobów. Zasoby te tworzą kontekst procesu. Zasobami tymi mogą być: - na poziomie użytkownika: zawartość przestrzeni adresowej i jego środowisko uruchomieniowe, - na poziomie jądra: oprócz wyżej wymienionych, parametry szeregowania (np. priorytet procesu) i parametry sterowania zasobami. Użytkownik może tworzyć procesy, sterować ich wykonywaniem i odbierać informację o zmianie statusu wykonywania. Każdy proces ma przydzieloną unikalną wartość, zwaną identyfikatorem procesu (PID). Wartość ta jest używana przez jądro do identyfikacji procesu oraz użytkownika do wywoływania funkcji systemowej. Jądro tworzy proces przez powielenie kontekstu innego procesu. Ten nowy proces zwany jest procesem potomnym oryginalnego procesu macierzystego z identyfikatorem PPID. Kontekst powielony przy tworzeniu procesu zawiera zarówno stan wykonywania procesu na poziomie użytkownika jak i jądra. Współistnienie procesów można zilustrować na przykładzie procesu powłoki, interpretującego polecenia użytkownika. Proces ten w chwili odczytania polecenia z klawiatury tworzy proces potomny odpowiedzialny za realizację tego polecenia. Standardowo proces macierzysty (czyli powłoka) oczekuje na zakończenie procesu potomnego i dopiero wówczas pobiera kolejne polecenia. Użytkownik może spowodować aby dane polecenie było wykonywane w tle. Wtedy proces powłoki nie czekając na zakończenie danego procesu potomnego, pobiera nowe polecenie i tworzy dla niego nowy proces.
Zarządzanie urządzeniami wejścia/wyjścia - w systemie UNIX, tak jak w wielu systemach operacyjnych, szczegóły urządzeń fizycznych są ukryte przed użytkownikiem. Jednakże rozwiązanie zastosowane w tym systemie jest unikalne. Zadanie ukrycia wspomnianych szczegółów należy do jądra - a ściślej do systemu zarządzania urządzeniami wejścia/wyjścia. Jak wiemy, w systemie UNIX wprowadzono zasadę, że urządzenia fizyczne są postrzegane przez użytkownika jako pliki. Osiągnięto to definiując urządzenie wirtualne funkcjonalnie odpowiadające dyskowi i pisząc specjalne programy obsługi urządzeń (device drivers), odwzorowujące operacje urządzenia wirtualnego w operacje urządzenia fizycznego. Ze względu na konieczność specjalnego traktowania przez system wspomnianych plików odpowiadających urządzeniom nazwano je plikami specjalnymi. Istnieją dwa podstawowe typy plików specjalnych: blokowe i znakowe. Pliki blokowe reprezentujące urządzenia blokowe, czyli dyski i taśmy. Pliki znakowe reprezentujące urządzenia znakowe, czyli terminale i drukarki. System wejścia/wyjścia składa się ze zbioru modułów obsługi urządzeń, zazwyczaj jednego modułu obsługi na urządzenie określonego typu. Moduły te są dołączane do sytemu operacyjnego podczas generowania jądra i nie mogą być później usuwane. Ich zadaniem jest odseparowanie reszty systemu od sprzętu. System wejścia/wyjścia systemu UNIX jest podzielony na dwie części, zgodnie z klasyfikacją urządzeń, tj. część obsługująca urządzenia blokowe i część obsługująca urządzenia znakowe. Celem części systemu, która obsługuje operacje wejścia/wyjścia urządzeń blokowych, czyli przede wszystkim dysków, jest minimalizacja liczby przesyłań do i z dysku. W tym celu stosuje się pamięć notatnikową buforów, która jest umieszczana między systemem plików a modułami obsługi dysków. Przy wykonywaniu operacji odczytu z urządzenia w pierwszej kolejności przeszukiwana jest pamięć notatnikowa buforów. Jeżeli w buforze znaleziono odpowiedni blok danych, to nie ma potrzeby wykonywania czasochłonnej operacji wejścia/wyjścia. Jeżeli nie znaleziono, to wyszukuje się bufor z listy wolnych buforów, aktualizuje się numer urządzenia i numer bloku i wykonuje operację odczytu do pamięci notatnikowej. Jeżeli nie ma wolnych buforów to wyszukuje się bufor z danymi które najdłużej czekały na zapis. Dane z tego bufora zostają zapisane na urządzenie wyjściowe a zwolniony bufor może być wykorzystany przez operację odczytu. Informacja o tym, że blok danych znajduje się w buforze, zawarta jest w nagłówku bufora. Pamięć notatnikowa jest wykorzystywana zarówno przy wykonywaniu operacji zapisu, jak i odczytu. W celu utrzymania spójności systemu plików w przypadku awarii zawartości pamięci notatnikowej, jest zapisywana na dysk co 30 sekund.
Mechanizm zarządzania pamięcią operacyjną różni się znacznie w zależności od wersji systemu. Jest to ściśle związane z ograniczeniami sprzętowymi. W wersjach systemu wcześniejszych niż UNIX 3 BSD oraz prostych wersjach systemu, wykorzystywanych na sprzęcie klasy PC technika wymiany obszarów pamięci pomiędzy pamięcią operacyjną, a dyskową jest stosowana w ograniczonym zakresie. To znaczy, że jeżeli w systemie znajduje się zbyt wiele procesów i brakuje wolnego obszaru pamięci operacyjnej, to niektóre z tych procesów są usuwane (często używa się pojęcia wymiatane  - and. swapping) na dysk, aż zwolni się wystarczająco duży obszar pamięci operacyjnej. Alokacja pamięci odbywa się w tego typu systemach według algorytmu FF (ang. First Fit). Jeśli w danej chwili nie ma odpowiednio dużo, spójnego obszaru pamięci proces ulega zawieszeniu. Decyzję o tym, który proces ma być wprowadzony do pamięci operacyjnej lub z niej usunięty, podejmuje proces zawiadowcy (scheduler) czyli proces 0 (w niektórych systemach zwany również pod nazwą swapper process) Proces zawiadowcy jest budzony okresowo (zazwyczaj co kilka sekund) i sprawdza które procesy powinny być usunięte z pamięci, a które do niej wprowadzone. W pierwszej kolejności są usuwane procesy najdłużej przebywające w pamięci lub procesy duże i podobnie wprowadzane są procesy, które były poza systemem najdłużej lub są małe. Aby uniknąć problemu migotania, nie pozwala się na usunięcie procesów, które nie przebywały w systemie przez określony czas. Taki schemat zarządzania pamięcią operacyjną wykorzystuje wiele wersji systemu UNIX: wszystkie systemy USG (UNIX Support Group) z wcześniejszymi wersjami UNIX System V włącznie. Technika stronicowania została wprowadzona po raz pierwszy w systemie UNIX 3 BSD. Obecnie wykorzystuje się ją w systemach UNIX BSD i najnowszych wersjach UNIX System V. Są to systemy z pamięcią wirtualną, ze stronicowaniem na żądanie. Technika ta jest realizowana w sposób bezpośredni, to znaczy, że jeżeli proces potrzebuje strony, której w danej chwili nie ma w pamięci operacyjnej, to do jądra systemu jest wysyłane przerwanie - "błąd strony", alokowana odpowiednia ramka w pamięci operacyjnej i właściwa strona czytana z dysku. Obraz pamięci operacyjnej w systemie UNIX 4 BSD - schemat:

[Rysunek jest przerysowny osobiście prze zemnie, część oryginalna znajduje się w książce, pt.: "System operacyjny UNIX dla początkujących i zaawansowanych" - Autorzy: Zbyszko Królikowski i Michał Sajkowski - str 124.]

W dolnym obszarze pamięci znajduje się jądro systemu a nad nim mapa pamięci (core map). Pozostała część pamięci operacyjnej jest podzielona na ramki stron, które mogą zawierać: tekst programu, segment danych, stos, strukturę użytkownika i tablicę odwzorowania stron lub mogą być po prostu nie wykorzystane. Mapa pamięci stanowi zbiór informacji o zawartości ramek stron. Pozycja numer 0 mapy pamięci opisuje ramkę stron nr. 0, pozycja numer 1 - ramkę nr. 1 itd. Ramki stron mają najczęściej rozmiar 1KB, natomiast poszczególne pozycje w mapie pamięci opisujące ramki są 16-bitowe. Z reguły mapa pamięci nie przekracza 2% całkowitego obszaru pamięci operacyjnej. Usuwanie stron z pamięci operacyjnej przebiega w dwóch etapach. Najpierw strona jest oznaczana w tablicy odwzorowania stron procesu jako nieważna i na razie w stosunku do niej nie są podejmowane żadne akcje. Jeżeli na tym etapie zostanie wygenerowany sygnał przerwania "błąd strony", to strona, której przerwanie to dotyczy, może być wtedy oznaczona jako ważna i można ją wykorzystać bez konieczności wykonywania operacji wejścia/wyjścia to jest sprowadzania ją z pamięci zewnętrznej. Najczęściej wykorzystuje się algorytm wymiany stron LRU. Algorytm ten opiera się na założeniu, że strona z pamięci operacyjnej, która najdłużej nie była wykorzystana, nie będzie prawdopodobnie wykorzystana w najbliższej przyszłości. Mapa pamięci operacyjnej (z wyłączeniem jądra) jest cyklicznie i liniowo przeglądana przez program o nazwie clock hand (w BSD - two handed clock, w System V - one handed clock). Jeżeli ramka jest wolna, program bada następną i jeżeli jest w niej wpisana jakaś strona, to następuje sprawdzenie odpowiedniego zapisu w tablicy odwzorowania stron. Jeżeli strona występuje jako nieważna, to jest usuwana, a ramka dodawana do listy ramek wolnych. Natomiast jeśli strona jest oznaczona jako ważna i aktualnie nie jest wykorzystywana przez operacje wejścia/wyjścia, to jest status ulega zmianie na nieważny i stronę pozostawia się na razie w spokoju. W systemie kontroli podlega również liczba stron ze statusem ważna, tak aby nie obniżyła się ona zbytnio, co mogło by spowodować nagły wzrost żądań sprowadzenia stron z pamięci dyskowej. Proces clock hand jest zaimplementowany jako część procesu 2 - pagedaemon (swapper jest procesem 0, init procesem 1). Proces ten większość czasu "śpi", lecz w tym czasie trwa sprawdzanie (kilka razy na sekundę), czy konieczna jest w systemie interwencja tego procesu. Jeżeli tak proces 2 zostaje obudzony, na przykład gdy liczba ramek w p.o. spadnie poniżej pewnej wartości progowej (lotsfree) - zazwyczaj 1/4 pamięci. Proces clock hand uwzględnia podczas pracy zarówno to, ile ramek brakuje do osiągnięcia wartości progowej, jak i wskazówek zawiadowcy. Jeżeli proces zawiadowcy zadecyduje że system jest przeładowany, to pewne procesy są z systemu usuwane, aż przeładowanie zniknie. Brane są przy tym pod uwagę pewne dodatkowe parametry, tj. minfree najniższy limit wolnej pamięci oraz desfree średni rozmiar dostępnej pamięci w ostatnim okresie. Innymi słowy procesy są usuwane, jeśli w systemie wystąpił brak pamięci. Omówiony mechanizm zarządzania pamięcią operacyjną jest mechanizmem systemowym, a więc ingerencje użytkowników są w nim niemożliwe. System UNIX dostarcza jednak pewne dodatkowe możliwości ingerowania w organizację pamięci wykorzystywanej przez programy aplikacyjne. Służy do tego zestaw funkcji systemowych, pozwalających na zdefiniowanie i manipulowanie tzw. pamięcią współdzieloną. Pamięć współdzielona (shared memory) służy do przekazywania danych między procesami. Obszar współdzielony musi zostać utworzony z wykorzystaniem funkcji systemowej shmget z argumentami klucz, rozmiar i tryb dostępu (inaczej - flagi dostępu - and. shmflag). Funkcja ta zwraca identyfikator obszaru. Każdy z procesów, który chce wymieniać dane poprzez ten obszar musi dołączyć go funkcją shmat, podając jako argumenty identyfikator uzyskany z shmget, adres pod którym proces chce widzieć obszar (gdy adres jest równy zero system przyłącza obszar pod pierwszym wolnym adresem) oraz flagi dostępu. Funkcja shmat zawiera adres, pod którym obszar współdzielony jest widoczny w danym procesie. Po zakończeniu korzystania z obszaru proces odłącza go wykonując funkcje shmdt, przekazując jako argument adres obszaru.