Systemy Operacyjne
ZARZĄDZANIE PROCESAMI
Proces to program w trakcie wykonywania. W nowoczesnych systemach z podziałem czasu proces jest jednostką pracy.
Proces to ciąg czynności wykonywanych za pośrednictwem ciągu rozkazów, których wynikiem jest wykonanie pewnych zadań systemowych lub programów użytkownika
Kilka procesów może być związanych z jednym programem.
W czasie wykonywania proces może tworzyć nowe procesy.
Ograniczenia systemów jednozadaniowych
W danej chwili system może realizować tylko jeden proces (jedno zadania)
Wszystkie pozostałe procesy, o ile istnieją, muszą czekać w kolejce do procesora
(do czasu, aż procesor będzie wolny
i będzie można ponownie przydzielić go jednemu z oczekujących procesów)
Potrzeba stosowania systemów wielozadaniowych
wieloprogramowania: jak najlepsze wykorzystanie procesora - powinien on „zawsze” wykonywać jakiś proces.
podział czasu: przełączanie procesora między procesami powinno następować tak często, aby każdy z programów, który tego wymaga mógł współpracować z użytkownikami w sposób interakcyjny.
Rodzaje procesów
niezależny (ang. independent), jeżeli nie może oddziaływać na inne procesy wykonywane w systemie, a te z kolei nie mogą wpływać na jego działanie. Mówiąc jaśniej, dowolny proces jest niezależny, jeśli nie dzieli żadnych danych (tymczasowych lub trwałych) z żadnym innym procesem
współpracujący (ang. cooperating), jeżeli może wpływać na inne procesy w systemie lub inne procesy mogą oddziaływać na niego. Dokładniej - dowolny proces dzielący dane z innymi procesami
Stan procesu
Nowy - proces został utworzony;
Aktywny - proces wykonuje instrukcje;
Oczekujący - proces czeka na wystąpienie jakiegoś zdarzenia;
Gotowy - proces czeka na przydział procesora;
Zakończony - proces zakończył działanie.
Diagram stanów procesu
Stany procesu w systemie LINUX
TASK_RUNNING - proces nadaje się do uruchomienia
TASK_INTERRUPTIBLE - proces jest zawieszony w oczekiwaniu na zajście pewnego zdarzenia lub otrzymanie sygnału
TASK UNINTERRUPTIBLE - proces jest zawieszony w oczekiwaniu na zajście pewnego zdarzenia
TASK_ZOMBIE - zadanie zostało zakończone, ale jego proces macierzysty nie zainicjował jeszcze wywołania systemowego wait4()
TASK_STOPED - wykonanie procesu zostało zatrzymane, zadanie już nie działa
Blok kontrolny procesu
Kolejki planowania
Kolejka procesów gotowych
Kolejki do urządzeń
Diagram kolejek w planowaniu procesów
Planiści
Planista długoterminowy (planista zadań)
Planista krótkoterminowy (planista przydziału procesora)
Planista średnioterminowy
Planista długoterminowy
Planista długoterminowy (ang. long-term scheduler), inaczej planista zadań (ang. job scheduler), wybiera procesy z puli zadań w pamięci pomocniczej i ładuje je do pamięci operacyjnej w celu wykonania.
Planista krótkoterminowy
Planista krótkoterminowy (ang. short-term scheduler), czyli planista przydziału procesora (ang. CPU scheduler), wybiera jeden proces spośród procesów gotowych do wykonania i przydziela mu procesor.
Planista krótkoterminowy a planista długoterminowy
Podstawową różnicą między obydwoma planistami jest częstość ich uaktywnień: krótkoterminowy musi bardzo często wybierać nowy proces dla procesora
Proces może działać zaledwie kilka ms, i przejść w stan oczekiwania po zamówieniu na operację wejścia-wyjścia
Planista krótkoterminowy a planista długoterminowy
Często planista krótkoterminowy podejmuje działanie co najmniej raz na każde 100 ms.
Planista krótkoterminowy musi być bardzo szybki (na krótkie odcinki czasu między kolejnymi wykonaniami). Jeśli decyzja o wykonaniu procesu przez 100 ms zabiera 10 ms, to 10/(100 + 10) = 9% pracy procesora jest zużywane (marnowane) na samo zaplanowanie działania
Planista krótkoterminowy a planista długoterminowy
Planista długoterminowy działa o wiele rzadziej: między utworzeniem nowych procesów w systemie mogą upływać minuty.
Planista długoterminowy nadzoruje stopień wieloprogramowości, tj. liczbę procesów w pamięci. Jeśli stopień wieloprogramowości jest stabilny, to średnia liczba utworzonych procesów musi się równać średniej liczbie procesów usuwanych z systemu.
Planista krótkoterminowy a planista długoterminowy
Planista długoterminowy może być wywoływany tylko wtedy, gdy jakiś proces opuszcza system. Wskutek dłuższych przerw między wykonaniami planista długoterminowy ma więcej czasu na rozstrzyganie, który proces należy wybrać do wykonania.
Wymiana procesów
Proces wysyłany z pamięci operacyjnej do pamięci zewnętrznej, a później wprowadzany do niej ponownie przez planistę średnioterminowego
Wymiana - niezbędna do uzyskania lepszego doboru procesów lub wówczas, gdy żądania przydziału pamięci przekraczają jej bieżący obszar i wymagają zwolnienia miejsc w pamięci
Zmniejsza wieloprogramowość
Rodzaje procesów z punktu widzenia planisty
Ograniczone przez wejście-wyjście - takie, które spędzają większość czasu na wykonywaniu operacji wejścia-wyjścia, mniej zajmując się obliczeniami.
Ograniczone przez dostęp do procesora -sporadycznie generują zamówienia na wejście-wyjście, więcej czasu poświęcają na obliczenia wykonywane przez procesor
Przełączanie kontekstu
Przełączanie kontekstu polega na przełączeniu procesora z aktualnie wykonywanego procesu do innego procesu. Operacja ta wymaga przechowania stanu aktualnie wykonywanego procesu i załadowania przechowywanego stanu nowego procesu.
Działania na procesach
Tworzenie nowych procesów
Kończenie procesów działających w systemie
Tworzenie nowego procesu w systemie UNIX
W systemie UNIX inicjalizacja nowego procesu wiąże się z wywołaniem dwóch funkcji fork() oraz exec().
Funkcja fork() tworzy proces potomny który jest kopią zadania inicjującego jej wywołanie.
Nowy proces różni się od procesu macierzystego jedynie: identyfikatorem PID, identyfikatorem PPID, zestawem przypisanych do procesu zasobów.
Tworzenie nowego procesu w systemie UNIX
Funkcja exec() wczytuje do przestrzeni adresowej procesu kod wykonywalny z pliku i inicjuje jego wykonanie
Tylko kombinacja funkcji fork() oraz exec() daje efekt w postaci zainicjowania nowego procesu.
Zakończenie procesu w systemie UNIX
Proces kończy działanie po zainicjowaniu z poziomu procesu wywołania systemowego exit().
Proces kończy działanie również w sytuacji otrzymania sygnału bądź powiadomienia o zdarzeniu, którego proces nie potrafi obsłużyć a nie może go zignorować.
Większość operacji związanych z usuwaniem procesu realizowana jest przez funkcję do_exit().
Zakończenie procesu w systemie UNIX
Po zakończeniu funkcji do_exit() wszystkie obiekty skojarzone z zamykanym procesem są zwalniane.
Zadanie nie nadaje się do ponownego uruchomienia i znajduje się w stanie TASK_ZOMBIE i podtrzymywane jest tylko jako źródło danych dla procesu macierzystego.
Kiedy proces macierzysty uzyska już potrzebne dane o zakończonym procesie potomnym zwalniany jest deskryptor tego ostatniego.
Komunikacja pomiędzy procesami
Wykorzystanie pamięci dzielonej - zagadnienie producenta i konsumenta
Wykorzystanie przekazywania komunikatów - operacje nadaj, odbierz komunikat
Wątek (proces lekki) jest podstawową jednostką wykorzystania procesora, w skład której wchodzą: licznik rozkazów, zbiór rejestrów, obszar stosu.
Sekcja kodu, sekcja danych oraz pozostałe zasoby wątek współużytkuje z innymi wątkami. Wątki umożliwiają programowanie współbieżne a na platformach wieloprocesorowych pozwalają na implementację prawdziwego przetwarzania równoległego.