background image

13. ZARZĄDZANIE PROCESAMI W SYSTEMIE OPERACYJNYM UNIX

Z punktu widzenia organizacji systemu Unix procesy są obiektami logicznymi 

posiadającymi swoje

atrybuty (zapisane w odpowiednich systemowych strukturach danych), na 

których można wykonywać

operacje przy użyciu odpowiednich funkcji systemowych.

Najważniejsze atrybuty procesów:

- identyfikator procesu PID 

(Process ID)

- identyfikator procesu rodzicielskiego PPID 

(Parent Process ID)

- rzeczywisty identyfikator użytkownika UID 

(User ID)

- efektywny identyfikator użytkownika EUID 

(Effective User ID)

- rzeczywisty identyfikator grupy użytkowników GID 

(Group ID)

- efektywny identyfikator grupy użytkowników EGID 

(Effective Group ID)

- identyfikator grupy procesów PGRP 

(Process Group)

background image

Proces może mieć swój terminal sterujący, z którym może komunikować się, 
pobierając z niego

dane (na przykład polecenia użytkownika) i wyświetlając wyniki. Jednym z 
atrybutów procesu jest

wskaźnik do struktury terminala - systemowej struktury danych związanej z 
danym terminalem.

Struktura terminala zawiera między innymi bieżący identyfikator grupy 
terminala
 

(Current

Terminal Process Group)

 - nie ma ustalonego skrótu, na potrzeby wykładu 

przyjmijmy CTPGRP.

Jeśli proces nie ma swojego terminala sterującego, jego wskaźnik ma wartość 
NULL.

W większości przypadków procesy użytkowników mają swój terminal sterujący 
(ten, z którego

zostały uruchomione), natomiast procesy systemowe nie mają swojego 
terminala (wykonują one

swoją pracę przez cały czas, niezależnie od tego, czy nadzorca systemu jest 
aktualnie zalogowany).

Procesy systemowe, mające za zadanie dostarczanie określonych usług na rzecz 
innych procesów,

nazywane są często serwerami tych usług lub demonami 

(daemon)

.

Zwykły użytkownik systemu również ma możliwość uruchamiania procesów 
„pozbawionych

terminala sterującego”, które mogą być wykonywane nawet po zakończeniu 
przez użytkownika sesji

pracy i wyłączeniu terminala (na przykład mogą wykonywać przez całą noc 
skomplikowane

obliczenia i zapisywać wyniki do pliku).

background image

Proces interpretatora komend, który zostaje uruchomiony w wyniku zalogowania 
się do systemu,

nazywany jest shellem zgłoszonym. Na początku pracy jest on procesem 
sterującym
 terminala, 

z którego nastąpiło zalogowanie, czyli przywódcą grupy terminala (zachodzi dla 
niego 

PID = PGRP = CTPGRP).

Proces nazywamy pierwszoplanowym 

(foreground process)

, jeżeli jego PGRP jest 

równy CTPGRP

wskazywanego przez niego terminala. W przeciwnym przypadku proces nazywamy 
drugoplanowym,

lub wykonującym się w tle 

(background process)

. Procesy pierwszoplanowe mogą 

odczytywać znaki

z terminala i zapisywać znaki do terminala (to jest pliku specjalnego 
odpowiadającego terminalowi).

Procesy drugoplanowe nie mogą odczytywać znaków z terminala (są zawieszane 
przy próbie czytania),

natomiast zazwyczaj mogą zapisywać znaki do terminala (jest to zależne od 
systemu i aktualnych

ustawień w strukturze terminala).

Uwaga.

Zazwyczaj w każdej chwili istnieje dokładnie jeden proces pierwszoplanowy 
terminala.

background image

Pojedynczą komendę lub pojedynczy potok komend uruchomiony z linii poleceń 
shella nazywamy

pracą 

(job)

. Shell ma własność sterowania pracami 

(job control)

, jeżeli posiada 

możliwość zmiany

CTPGRP terminala, z którego został uruchomiony.

Polecenia:

komenda                                 - uruchamia proces pierwszoplanowy;

komenda &                             - uruchamia proces drugoplanowy 

(komenda &)                          - uruchamia proces drugoplanowy korzystając z 
podshella

Ctrl-Z                                     - zawiesza proces pierwszoplanowy

Ctrl-Y                                    - zawiesza proces pierwszoplanowy w chwili 
rozpoczęcia czytania

bg praca   (lub   praca &)     - uruchamia zawieszony proces w tle

fg praca    (lub   praca )        - uruchamia zawieszony proces na pierwszym planie

kill -9  PID                            - powoduje zakończenie procesu (działającego lub 
zawieszonego)

Uwaga. Można uruchomić kilka procesów jednocześnie z jednej linii poleceń 
(pisząc na przykład

              komenda_1 &   komenda_2 & ).

background image

Do uzyskiwania informacji o aktualnie wykonywanych procesach (numerach, 
właścicielach, stanach

procesów itp.) służy polecenie zewnętrzne  ps. W zależności od podanych opcji 
może wyświetlać

jedynie informacje o aktywnych procesach lub o wszystkich (też zawieszonych), 
informacje jedynie

o procesach użytkownika wydającego polecenie, lub o wszystkich procesach w 
systemie (ta ostatnia

opcja zwykle nie jest udostępniana dla użytkowników nieuprzywilejowanych).

Uwaga

Użytkownik może badać stan swoich procesów związanych z bieżącą sesją przy 
użyciu interpretera

komend bieżącej sesji (w takim przypadku proces interpretera musi być 
pierwszoplanowy, a wszystkie

inne procesy drugoplanowe lub zawieszone), lub też otwierając nową sesję (i 
uruchamiając w ten

sposób nowy proces interpretera) i z niej sprawdzając stan procesów pierwszej 
sesji. Jest to możliwe,

bo użytkownik jest właścicielem wszystkich procesów zarówno pierwszej, jak i 
drugiej sesji.

Drugi sposób jest lepszy, jeśli z jakichś powodów nie jest wskazane czasowe 
przerywanie pracy

procesu pierwszoplanowego pierwszej sesji.

background image

Pełny diagram stanów procesu  (według  [ M. Bach ] ):

                                                                                          Wykonywany w trybie użytkownika

                                                                           wywołanie      

                                                                       funkcji systemowej,                                        powrót do trybu

                                            przerwanie                przerwanie          powrót                                 
użytkownika

                                              i powrót                                                     wywłaszczenie

                                                                                             Wykonywany w trybie jądra

                                                         wyjście                                                                                                 
Wywłaszczony

                               Zombie                                                         ponowne

                                                zasypia                                          uszeregowanie

                                                                                                                         Gotowy do wykonania w 
pamięci

                       Uśpiony                                   budzi się

                      w pamięci                                                                                                  dość pamięci

                                                 usunięcie                             usunięcie         sprowadzenie              
Utworzony

                                                 z pamięci                             z pamięci        do pamięci                                
fork

                       Uśpiony                                  budzi się                                                  za mało pamięci

              poza pamięcią                                                                                     Gotowy do wykonania 
poza pamięcią

Uwaga. Powyższy diagram nie uwzględnia mechanizmu stronicowania pamięci.

background image

Jądro utrzymuje globalną strukturę nazywaną tablicą procesów, której zajęte 
pozycje odpowiadają

identyfikatorom procesów aktualnie istniejących w systemie (typowa wielkość 
tablicy procesów -

32768 pozycje). Każda zajęta pozycja zawiera między innymi:

- pole stanu procesu;

- identyfikator właściciela procesu (UID);

- wskaźnik do tablicy segmentów procesu;

- wskaźnik do u-obszaru 

(u-area, user area) 

procesu.                         Tablica 

segmentów

           U-obszar

                                                                   Tablica segmentów 

                                                                             procesu

                                  Tablica procesów                                     Pamięć  
operacyjna

background image

Tablica procesów jest strukturą globalną, do której dostęp ma jedynie jądro 
systemu. Z każdym

wykonywanym procesem związany jest jego u-obszar, do którego dostęp ma 
zarówno jądro, jak

i sam proces (gdy wykonywany jest w trybie jądra). U-obszar zawiera między 
innymi:

- wskaźnik do odpowiadającej mu pozycji w tablicy procesów;

- deskryptory plików otwartych przez dany proces;

- nazwę bieżącego katalogu;

- argumenty aktualnego wywołania funkcji systemowej, zwracane wartości i kod 
błędu.

Z każdym wykonywanym procesem związana jest też tablica segmentów 
procesu
, która zawiera

opisy segmentów przydzielonych procesowi (kodu, danych, stosu, pamięci 
wspólnej) wraz ze

wskaźnikami do odpowiednich pozycji w globalnej tablicy segmentów. Tablica 
segmentów, 

utrzymywana przez jądro segmentów, zawiera z kolei deskryptory wszystkich 
istniejących segmentów

w pamięci operacyjnej. Taki dwustopniowy system adresowania segmentów w 
pamięci umożliwia

współdzielenie segmentów przez wiele procesów, przy jednoczesnym zachowaniu 
możliwości ich

ochrony (na przykład jeden proces może mieć prawo do zapisu w danym 
segmencie, a pozostałe tylko

do odczytu).

background image

Każdy proces, poza procesem rozpoczynającym pracę systemu, powstaje w wyniku 
utworzenia przez

inny proces. Proces uruchamiający jądro systemu jest tworzony „bezpośrednio” i 
otrzymuje numer 0.

Jest on procesem wykonywanym w trybie jądra. Po uruchomieniu systemu 
przyjmuje on rolę procesu

wymiany. Tworzy on proces init o numerze 1, który jest procesem wykonywanym 
w trybie użytkow-

nika, i który zajmuje się dalej tworzeniem procesów potomnych. Init jest zatem 
przodkiem wszystkich

procesów w systemie poza procesem 0.

Każdy proces ma prawo tworzyć swoje procesy potomne (ich liczba jest 
ograniczona pojemnością

tablicy procesów oraz, ewentualnie, maksymalną liczbą procesów należących do 
jednego użytkownika).

W klasycznych systemach uniksowych proces potomny powstawał zawsze wskutek 
wywołania przez

proces rodzicielski funkcji systemowej fork (obecnie takich funkcji jest więcej, co 
jest między innymi

związane z implementacją wątków, czyli procesów lekkich). Utworzony proces 
potomny jest wpisywany

do tablicy procesów na kolejnej wolnej pozycji (modulo rozmiar tablicy), której 
numer staje się jego

identyfikatorem. Każdy proces „pamięta” identyfikator swojego procesu 
rodzicielskiego, natomiast

spośród identyfikatorów procesów potomnych pamięta jedynie ostatni (najpóżniej 
przydzielony).

background image

Każdy nowo utworzony proces dziedziczy identyfikator grupy procesów (PGRP) 
po swoim procesie

rodzicielskim. Może w tej grupie pozostać lub wywołać funkcję systemową 
setpgrp, która powoduje

zmianę jego dotychczasowego PGRP na wartość jego identyfikatora (PID). 
Proces, który wywołał

setpgrp, staje się przywódcą grupy procesów.

Proces potomny dziedziczy po swoim procesie rodzicielskim większość jego 
atrybutów - UID, GID,

deskryptory przydzielonych zasobów systemowych (w szczególności deskryptory 
otwartych plików)

i zbiór zmiennych środowiska. Dziedziczy również segment kodu programu oraz 
otrzymuje kopie

segmentu danych i stosu. Ponieważ zazwyczaj celem utworzenia nowego 
procesu jest powierzenie

mu wykonywania innego programu, niż wykonuje jego proces rodzicielski, 
proces potomny powinien

wywołać funkcję systemową exec, której argumentem jest nazwa pliku z innym 
programem.

Proces potomny, kończąc działanie (wywołując funkcję systemową exit) przesyła 
informację o tym

do swojego procesu rodzicielskiego, przekazując mu jednocześnie swój kod 
zakończenia
 

(exit code)

,

będący niedużą liczbą całkowitą (0 w przypadku traktowanym jako pomyślny). 
Jeśli proces rodziciel-

ski zakończył działanie przed zakończeniem wszystkich jego procesów 
potomnych, automatycznie

„przybranym rodzicem” dla niezakończonych procesów potomnych staje się 
proces init.

background image

Priorytet procesu, decydujący o częstości wybierania go do wykonywania przez 
procesor, zależny jest

od kilku wielkości, między innymi od współczynnika  nice  (nazywanego też 
poziomem uprzejmości 

procesu) umieszczonego w odpowiadającej danemu procesowi pozycji tablicy 
procesów.

Współczynnik ten może mieć wartość z zakresu  0 ... 39 , przy czym niższa 
wartość współczynnika

oznacza podwyższenie priorytetu.

Standardowa wartość nice wynosi 20 - wartość tę dziedziczą między innymi 
wszystkie shelle 

zgłoszone pośrednio od procesu init (przez domniemanie każdy proces dziedziczy 
wartość nice po

swoim procesie rodzicielskim). Użytkownicy nieuprzywilejowani mogą 
uruchamiać procesy ze

współczynnikiem nice równym 20 lub więcej (do jego zwiększania służy polecenie 
systemowe nice).

Tylko nadzorca systemu może uruchamiać procesy z dowolnym współczynnikiem 
nice.

Uwaga

W dawniejszych systemach uniksowych wartość nice mogła być zmieniana 
jedynie przez proces,

którego ta wartość dotyczyła i nawet nadzorca systemu nie mógł wpływać na 
priorytety procesów

użytkowników. Obecnie możliwość taka istnieje (polecenie renice).

background image

Procesy mogą korzystać z pomiaru czasu prowadzonego przez system i ustalać 
pory wykonywania

różnych czynności (na przykład tworzenia nowych procesów, wysyłania 
komunikatów itd.) poprzez

zapisywanie ich w tablicach crontab (związanych z poszczególnymi 
użytkownikami systemu).

Tablice te są sukcesywnie przeglądane przez proces demona zegarowego cron
który w podanych

porach inicjuje wykonywanie podanych komend.

Do operowania na zawartości tablicy  crontab  służy polecenie o takiej samej 
nazwie. Innymi

poleceniami związanymi z pomiarem czasu i wykonywaniem pewnych czynności 
w ustalonych

porach są polecenia  at  oraz  leave.

Polecenia związane z pomiarem czasu ogólnie są uważane za polecenia 
niebezpieczne z punktu

widzenia systemu operacyjnego (nie są starannie opracowane pod kątem 
zabezpieczenia przed

włamaniami). W systemach uniksowych są zazwyczaj przechowywane listy 
użytkowników (ustalane

przez administratora), którzy albo a) mają prawo do wykonywania konkretnych 
poleceń związanych

z pomiarem czasu, albo b) mają zakaz wykonywania konkretnych poleceń.


Document Outline