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!
Liczba komentarzy: 15
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>


“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
> $ kill `pidof mplayer`
wystarczy pkill
wystarzczy killall mplayer
killall nie wszedzie mialem, a pkill owszem
htop jako alternatywa dla top by się przydał
Przydatny art, nawet sobie druknalem
“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
“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
a jeszcze przydatniejsze killall5 (nie stosować będąc w sesji X)
“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.
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)
“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
tutaj dokładniej i techniczniej :
http://students.mimuw.edu.pl/SO-ZSI/Wyklady-html/1_linux.html
A to Ci ciekawostka - myslalem ze init ma PID rowny 1 a nie zero.
- 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)
$ 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