Procesy w Linuksie

29 października 2007, adz

Jak zapowiadaliśmy, kontynuujemy sagę na temat konsoli i zaawansowanych technik związanych z niskopoziomową obsługą Linuksa. Dziś poznamy tajniki procesów, dowiemy się jak nimi zarządzać, nadawać im priorytet czy… wręcz zabijać(!)

Na początek anegdotka:

W pubie siedzi grupka informatyków, obok grupka dresiarzy. Drudzy zachowują się agresywnie i podśmiewają się z postury geeków i ich flanelowych wdzianek. Atmosfera gęstnieje, nie wiadomo czy nie dojdzie do awantury. Wtem… dzwoni telefon.
[odbiera informatyk]
- Co??? W ogóle ci nie odpowiada? W ogóle się ciebie nie słucha? Próbowałeś już “nice”? Taak? Nic nie dało..? Ok. Dobra — skilluj go.
[odkłada słuchawkę]
W tym momencie najbardziej napakowany z dresów wstaje i z wielkim podziwem odzywa się do informatyka:
- Szacun.

To tym dowcipnym wstępie przejdźmy od razu do rzeczy.

1. Podstawy

Na początek warto poznać definicję procesu, oraz kilka innych terminów z nim związanych. Mówiąc najogólniej proces jest wykonywanym programem, który posiada pewien stan:

  • nowy - proces właśnie został utworzony
  • gotowy - proces znajduje się w pamięci czeka na wykonanie swojego kodu przez procesor
  • działający - proces, który aktualnie jest wykonywany przez procesor
  • zablokowany - proces oczekujący na przydzielenie danego zasobu
  • zakończony - proces kończący działanie

Proces otrzymuje dostęp do zasobów takich jak np.: procesor, pamięć, pliki, urządzenia wejścia - wyjścia. Każdy posiada swój unikalny identyfikator liczbowy PID (ang. Process ID) oraz identyfikator rodzica (PPID - ang. Parent Process ID) czyli procesu który go utworzył. Tak więc uruchomione procesy można przedstawić w formie drzewa, w którego korzeniu znajdować się będzie proces z PID równym jeden - init, uruchamiany jako pierwszy po załadowaniu jądra. Podobnie jak pliki procesy posiadają swoich właścicieli, zazwyczaj są to użytkownicy którzy uruchomili dany program, wyjątkiem jest tu program z ustawionym bitem setuid lub też setgid. Prawa dostępu do zasobów systemu (np. plików w katalogu /dev), użytkownika który uruchomił proces, określają prawa dostępu jakie będzie posiadał proces. Do komunikacji z procesami wykorzystywane są tzw. sygnały. Programy uruchomione są z różnym priorytetem, określanym liczbą nice, przyjmującą wartości od -20 (najwyższy) do 19 (najniższy), domyślna wartość to 0.

2. fg, bg, jobs

Terminal umożliwia uruchamianie kilku programów naraz, przełączanie się pomiędzy nimi polega na przesuwaniu programu z “pierwszego planu” w “tło”. Tylko pierwszoplanowy proces może odbierać dane od użytkownika. Przesuwanie procesów z tła na pierwszy plan i w drugą stronę porównać można do aktywnego okna które przykrywa, pozostałe, nieaktywne okna.

Aby uruchomić program w tle wystarczy na końcu polecenia dostawić znak & (ang. Ampersand).

 

$ mpg123 -q plik.mp3&
[1] 638
$

Uruchamiając mpg123 w tle mogę słuchać muzyki mając cały czas dostęp do powłoki. Powłoka w nawiasie kwadratowym podała mi numer zadania (ang. job) - 1, oraz numer PID - 638.

Aby wyświetlić listę uruchomionych w tle zadań, należy użyć polecenia jobs, posiada ono dodatkowy parametr -l podający dodatkowo numer PID danego zadania.

Aby zatrzymać proces pierwszoplanowy należy użyć kombinacji Ctrl + z (w tym przypadku do procesu zostanie wysłany sygnał SIGSTP), aby zatrzymać proces można posłużyć się kombinacją Ctrl + c, przesłany zostanie do procesu sygnał SIGINT .

 

$ jobs -l
[1]-   638 Running                 mpg123 -q plik.mp3 &
[2]+   878 Stopped (tty output)    mc

W tle uruchomione zostały dwa zadania, mpg123 jest uruchomiony ponieważ do działania nie potrzebuje interakcji z użytkownikiem, mc jest zatrzymany i czeka na dane od użytkownika.

Aby dany proces uczynić pierwszoplanowym, należy posłużyć się poleceniem fg %numer zadania, lub fg %?nazwa plecenia lub fragment nazwy.

 

$ fg %1
$ fg %mpg

W pierwszym przypadku przeniosłem zadanie na pierwszy plan odwołując się do jego numeru zadania, w drugim odwołując się po fragmencie nazwy.

Polecenie fg %numer zadania, uruchomi zatrzymane w tle zadanie, w przeciwieństwie do polecenia fg, nie przeniesie zadania na pierwszy plan.

 

$ mpg123 -q plik.mp3
Ctrl + z
[3]+  Stopped                 mpg123 -q plik.mp3
$ bg %3
[3]+ mpg123 -q plik.mp3 &

Na koniec warto zwrócić uwagę na jeden fakt, na ekranie pojawią się dane wysyłane przez program w tle na standardowe wyjście, wyjście błędów, aby tego uniknąć można przekierować strumień do śmietnika np.polecenie > /dev/null

3. ps, pstree

Przedstawione wcześniej polecenie jobs, wyświetlało procesy uruchomione na danym terminalu. Aby wyświetlić szczegółowy spis procesów uruchomionych w systemie można posłużyć się poleceniem ps, uruchomione bez parametrów zadziała tak jak jobs. Pełny spis wszystkich parametrów dostępny jest w podręczniku tego polecenia (man ps), poniżej kilka najciekawszych opcji:

  • -e wyświetli każdy proces uruchomiony w systemie
  • -l szczegółowy opis
  • -f opis szczegółowy, krótszy od -l
  • -H pokazuje spis procesów w formie drzewa
  • a wyświetla wszystkie procesy
  • x wyświetla procesy uruchomione bez terminala
  • u podaje nazwę użytkownika który uruchomił proces
  • f wyświetla procesy w formie drzewa

Ps przyjmuje parametry w dwóch, nie kompatybilnych ze sobą, formatach: System V (parametry z myślnikiem -), oraz BSD. Wyjście polecenia z parametrami aux będzie wyglądać:

$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1   2952  1852 ?        Ss   10:49   0:01 /sbin/init
adam      5623  0.0  0.6  27892  7100 ?        Ssl  10:51   0:00 /usr/bin/gnome-session
adam      6815  0.2  1.6  39880 16728 ?        S    11:11   0:14 gedit
adam      7105  0.0  0.2   5708  3060 pts/1    Ss   11:16   0:00 bash

Poszczególne kolumny oznaczają:

  • USER - nazwa użytkownika, właściciela procesu
  • PID - identyfikator procesu
  • %CPU - szacowany procent użycia procesora, obliczany poprzez podzielenie czasu użycia procesora przez proces, przez czas uruchomienia
  • %MEM - szacowany procent użycia pamięci
  • VSZ - ilość użytej pamięci wirtualnej w KB
  • RSS - wykorzystana pamięć fizyczna w KB
  • TTY - terminal na którym uruchomiono proces
  • STAT - stan procesu, D oczekujący na dane z I\O, R działający, S uśpiony, T zatrzymany, X proces martwy(nie powinien być wyświetlany), Z proces zombie
  • START - godzina uruchomienia procesu
  • TIME - łączny czas zużycia procesora
  • COMMAND - polecenie które uruchomiło proces

Polecenie pstree, wyświetla procesy w formie drzewa, posiada parametr -a wyświetlający polecenie które uruchomiło proces.

$ pstree -a
init
  ├─cupsd
  ├─dbus-daemon --system
  ├─gedit
  └─gnome-terminal
      ├─bash
      │   └─man ps
      │       └─pager -s
      ├─bash
      │   └─man ps
      │       └─pager -s
      └─bash
          └─pstree -a

3. top

Polecenie top umożliwia podgląd uruchomionych procesów w systemie w czasie rzeczywistym. Parametr -u nazwa użytkownika umożliwia podgląd procesów uruchomionych tylko wybranego użytkownika, -pPID pozwala na podgląd procesu o określonym PID, przy czym parametr ten może zostać podany do 20 razy.

$ top
top - 17:38:09 up 43 min,  2 users,  load average: 0.32, 0.17, 0.06
Tasks: 124 total,   1 running, 123 sleeping,   0 stopped,   0 zombie
Cpu(s):  1.5%us,  0.2%sy,  0.0%ni, 98.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1026304k total,   560996k used,   465308k free,    42120k buffers
Swap:  1020116k total,        0k used,  1020116k free,   246652k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 7391 adam      15   0  189m  56m  21m S    3  5.6   0:20.42 firefox-bin
 7517 adam      15   0  2368 1164  876 R    1  0.1   0:00.03 top
 4029 root      13  -2  1744  384  280 S    0  0.0   0:00.76 ipw3945d-2

Aby zamknąć program należy posłużyć się przyciskiem q, niektóre przydatne skróty:

  • F lub O zmienia kolejność sortowania
  • spacja odświeża ekran
  • < ,> zmienia kolejność sortowania, wg. wyświetlanych kolumn
  • r zmienia wartość nice procesu
  • W zapisuje bieżące ustawienia top do pliku ~/.toprc
  • k wysyła sygnał do procesu

4. htop

Htop wyświetla listę procesów w bardziej rozbudowanej graficznie formie, program ten korzysta z biblioteki ncurses, zazwyczaj nie jest domyślnie dostępny.

  • kursory - poruszanie się pomiędzy procesami
  • F1 - menu pomocy
  • F2 - ustawienia
  • F3 - wyszukaj proces
  • F4 - odwraca sortowanie
  • F5 - wyświetla procesy w formie drzewa
  • F6 - zmienia kolejność sortowania
  • F7 - zmniejsza priorytet wybranego procesu
  • F8 - zwiększa priorytet wybranego procesu
  • F9 - wysyła sygnał do procesu
  • F10 - kończy program

5. kill

Wysyła sygnały procesom, składnia to kill sygnał PID, domyślny sygnał to SIGTERM (wartość liczbowa: 15), “delikatnie” kończący działanie programu pozwalający zamknąć otwarte pliki i “posprzątać” po swoim działaniu. Mocniejszym w działaniu procesem jest SIGKILL (wartość 9) wymuszający natychmiastowe zakończenie programu, sygnały SIGSTOP oraz SIGCONT odpowiednio zatrzymują i wznawiają wykonanie procesu. Procesowi można wysłać sygnał używając jego nazwy, lub korzystając z wartości liczbowej.

kill -SIGKILL 7496
kill -9 7496

W obu przypadkach zostanie “zabity” proces od PID 7496.

6. killall

W tym poleceniu moża przesłać sygnał wykorzystując nazwę procesu (można użyć wyrażeń regularnych) np.:

killall mplayer

Zabije wszystkie procesy o nazwie mplayer. Ciekawym parametrem jest -l, wyświetlający wszystkie możliwe sygnały. W niektórych systemach np. Solaris polecenie to zabija wszystkie procesy jakie użytkownik jest w stanie zabić, uruchomione przez roota zakończy działanie systemu.

7. nohup

Polecenie to związane jest z sygnałem SIGHUP. Historycznie sygnał ten informował o utracie połączenia z terminalem. Obecnie wykorzystywany jest do informowania, że pseudo-terminal na którym uruchomiono program zakończył działanie, przez co programy uruchomione na tym terminalu też są kończone. Proces uruchomiony z poleceniem nohup będzie ignorował ten sygnał.

$ nohup pidgin
nohup: dołączanie wyników do `nohup.out'

Jeżeli wcześniej wyjście programu nie zostało przekierowane do pliku, nohup domyślnie przekieruje je donohup.out.

8. pidof, pgrep

To dwa małe ale przydatne polecenia, podają one PID polecenia.

$ pidof nautilus
5668
$ pgrep nautilus
5668

Pgrep posiada parametr -l, wyścielający nazwę programu i PID, oraz parametry -u nazwa użytkownika, -G nazwa grupy wyświetlający procesy należące do danego użytkownika lub grupy.

$ kill `pidof mplayer`

W powyższym przykładzie wykorzystałem pidof do zamknięcia mplayera nieznając jego numeru PID.

9. renice

Polecenie to zmienia priorytet procesu, najwyższy priorytet to -20, najniższy to 19. Priorytety zmniejszać może tylko root.

$ renice 19 `pidof top`
12344: old priority 0, new priority 19

Parametr -u nazwa użytkownika zmieni priorytet wszystkim procesom których właścicielem jest podany użytkownik, -g nazwa grupy podana grupa.

$ renice 5 -u adam
1000: old priority 2, new priority 5

Ten artykuł jest częścią serii “Wszystko o konsoli” tworzonej na wiki projekt jakilinux.org przez społeczność związaną z wortalem pod przewodnictwem Adama Zielińskiego. Jeśli chciałbyś napisać kolejną część artykułu, po prostu napisz do Adama albo stwórz zalążek artykułu na wiki!

Komentarze (RSS)

Komentarze są prywatnymi opiniami dodających je osób. Prosimy o zachowanie kultury wypowiedzi. Komentarze obraźliwe oraz obniżające poziom serwisu będą usuwane. Więcej w regulaminie komentowania.

Liczba komentarzy: 15

zwiń wątek bns  30 października 2007 o godz. 0:04 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

“Tak więc uruchomione procesy można przedstawić w formie drzewa, w którego korzeniu znajdować się będzie proces z PID równym zero - init, uruchamiany jako pierwszy po załadowaniu jądra” init ma numer PID 1, a nie zero.

Pozatym przydatna lektora

Pozdrawiam

 
zwiń wątek azhag  30 października 2007 o godz. 0:43 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: +3 [Pokaż komentarz]

> $ kill `pidof mplayer`
wystarczy pkill

zwiń wątek witek  30 października 2007 o godz. 2:50 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

wystarzczy killall mplayer

zwiń wątek y0g1  2 listopada 2007 o godz. 22:33 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

killall nie wszedzie mialem, a pkill owszem

(Poniżej tego poziomu komentarze nie będą zagnieżdżane)
 
 
 
zwiń wątek AdamK  30 października 2007 o godz. 8:23 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]

htop jako alternatywa dla top by się przydał

 
zwiń wątek Ithanoss  30 października 2007 o godz. 9:40 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

Przydatny art, nawet sobie druknalem :)

 
zwiń wątek dos  30 października 2007 o godz. 13:33 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]

“Aby zatrzymać proces pierwszoplanowy należy użyć kombinacji Ctrl + z (w tym przypadku do procesu zostanie wysłany sygnał SIGSTP), aby zatrzymać proces można posłużyć się kombinacją Ctrl + c, przesłany zostanie do procesu sygnał SIGINT .”

Coś mi tu nie pasuje :P

“Polecenie fg %numer zadania, uruchomi zatrzymane w tle zadanie, w przeciwieństwie do polecenia fg, nie przeniesie zadania na pierwszy plan.”

Tu także…

Apropo konsoli to jeszcze przydatne jest polecenie killall :)

zwiń wątek hind  30 października 2007 o godz. 20:35 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]

a jeszcze przydatniejsze killall5 (nie stosować będąc w sesji X)

 
zwiń wątek el.pescado  31 października 2007 o godz. 23:53 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]

“Aby zatrzymać proces pierwszoplanowy należy użyć kombinacji Ctrl + z (w tym przypadku do procesu zostanie wysłany sygnał SIGSTP), aby zatrzymać proces można posłużyć się kombinacją Ctrl + c, przesłany zostanie do procesu sygnał SIGINT .”

Ctrl+Z zatrzymuje wykonanie bieżącego procesu (w sensie: pauzuje).
Ctrl+C kończy wykonanie procesu (w sensie: wyłącza).

“Polecenie fg %numer zadania, uruchomi zatrzymane w tle zadanie, w przeciwieństwie do polecenia fg, nie przeniesie zadania na pierwszy plan.”

fg wznawia wykonanie zatrzymanego (np, za pomocą Ctrl+Z) procesu.

 
 
zwiń wątek pi00  31 października 2007 o godz. 13:46 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]

zstyle ‘:completion:*:kill:*’ command ‘ps -u $USER -o pid,%cpu,tty,cputime,cmd’
zstyle ‘:completion:*:kill:*’ insert-ids single
zstyle ‘:completion:*:*:kill:*’ menu yes select
zstyle ‘:completion:*:kill:*’ force-list always

Ladne kill w zsh + dopełnianie dla procesów usera
Daje to nam liste procesów, po kolejnych mozemy przeskakiwac tabulatorem.
Przykładowo daję kill mp[TAB] i zabijam mplayera (nazwa sama zamienia się w PID)

 
zwiń wątek Taeril  31 października 2007 o godz. 22:40 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]

“identyfikator rodzica (PPID - ang. Parent Process ID) czyli procesu który go utworzył.” - init nie uruchomił zapewne wszystkich procesów jakie widzisz z PPID równym 1 bo on przejmuje te procesy, których rodzic nie istnieje. PPID nie może przecież wskazywać na nieistniejący już proces więc init jest takim sierocińcem :)

 
zwiń wątek wolvverine  1 listopada 2007 o godz. 7:07 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: -1 [Pokaż komentarz]
 
zwiń wątek out  5 listopada 2007 o godz. 22:26 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

Tak więc uruchomione procesy można przedstawić w formie drzewa, w którego korzeniu znajdować się będzie proces z PID równym zero - init, uruchamiany jako pierwszy po załadowaniu jądra.

A to Ci ciekawostka - myslalem ze init ma PID rowny 1 a nie zero.

 
zwiń wątek Lorniel  11 listopada 2007 o godz. 20:58 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

Pgrep posiada parametr -l, wyścielający nazwę programu i PID

- hmmm… no to wskoczyliśmy do łóżka :o) chodziło chyba o “wyświetlający”…
- to nie parametr wyświetla coś, tylko polecenie/program; parametr zmienia sposób wyświetlania wyników lub polecenie uruchomione z parametrem (…) wyświetla…

Bardzo przydatny artykuł :o)

 
zwiń wątek laik555  12 listopada 2007 o godz. 2:17 # Zwiększ karmę Zmniejsz karmę Cofnij swój głos Zgłoś komentarz do usunięcia KARMA: 0 [Pokaż komentarz]

$ renice 19 `pidof top`

Jeżeli priorytety może zmniejszać jedynie root, to odpowiednie będzie chyba:

$ sudo renice 19 `pidof top`

albo

# renice 19 `pidof top`

ale mogę się mylić, jestem lamerem, używam Windows ;)

 
Identyfikator (wymagane)
Adres e-mail (wymagany - nie pokażemy go publicznie)
Adres URI
Rozmiar pola: zmniejsz rozmiar | zwiększ rozmiar
Uwaga! Niektóre komentarze, m.in. te dodane przez niezalogowanych i nowych użytkowników, są ręcznie moderowane. Jeśli Twój komentarz nie ukaże się od razu, nie dodawaj go ponownie, tylko cierpliwie poczekaj na akceptację.

Literówki najlepiej zgłaszać jabberem: michuk@jakilinux.org lub kocio@jabber.org!

W komentarzach możesz używać prostych znaczników HTML. Przykłady:
  • Link: <a href="jaklinux.org">Linux dla każdego</a>,
  • Wytłuszczenie: <strong>tekst pogrubiony</strong>,
  • Kursywa: <em>tekst pochylony</em>,
  • Przekreślenie: <strike>tekst przekreślony</strike>,
  • Kod: <code>printf("blok kodu");</code>,
  • Cytat: <blockquote>cytat</blockquote>
Uwaga: jeśli dodasz nieznany znacznik, będzie on niewidoczny, gdyż system filtruje takie znaczniki.