Htop – monitorowanie procesów, przykłady stanów procesów
Cześć,
staram się ogólnie pisać coraz częściej tu i nawet w miarę mi się to udaje.
Tym wpisem chce zacząć cykl w którym pokażę Wam kilka narzędzi do monitorowania/administrowania/zarządzania itp serwerami:) Oczywiście linuxowymi.
Analiza aplikacji
Zaczniemy więc od klasyki – czyli od htopa.
Htop to młodszy brat top’a lub jak niektórzy wolą – top na sterydach. Top to narzędzie pokazujące aktualne obciążenie maszyny. Podobnie jest z htop’em.
Aby sobie go zainstalować wystarczy wykonać
1 | sudo dnf install htop |
i już.
Po uruchomieniu htop wygląda tak:
Zacznijmy od lewego górnego rogu:
Dla każdego rdzenia procesora htop rysuje jeden wykres. Na screenie widzimy 4 wykresy, więc oznacza to że mój procesor ma 4 rdzenie.
Każdy z tych wykresów pokazuje obciążenie rdzenia. Wykres jest kolorowy a poszczególne kolory to:
Niebieski – procesy o niskim priorytecie
Zielony – normalne procesy użytkownika
Czerwony – procesy jądra (w pewnym uproszczeniu – procesy systemu operacyjnego)
Turkusowy – procesy służące do wirtualizacji
Pod procesorem mamy dwie metryki pamięci – jedna (Mem) określa zajętość pamięci fizycznej w 3 kolorach:
Zielony – pamięć zajęta
Niebieski – zbuforowane strony pamięci
Żółty – cache.
Co do Swp – informuje o partycji wymiany i posiada tylko jeden kolor – zielony, określający ile jest jej zajęte.
Po prawej natomiast widzimy coś takiego:
i pierwsza linijka mówi że na naszym komputerze działa aktualnie aktywnie jeden proces, 196 procesów (tasków) działa ale aktualnie nie robi nic zajmującego procesor i wszystkie te zadania są podzielone na 830 wątków.
Druga linijka to opis obciążanie maszyny – określają one odpowiednie obciążenie maszyny w ostatniej minucie, 5 minutach i 15 minutach. Obciążanie tu pokazane można określić jako procent utylizacji maszyny (CPU) – wartość 1 oznacza 100% użycia jednego rdzenia.
Uptime to oczywiście informacja o tym jak długo maszyna działa od ostatniego restartu.
Skoro górną cześć htopa mamy za sobą, przejdźmy do listy procesów.
Kolumny od lewej oznaczają:
PID – identyfikator procesu
User – właściciel procesu (użytkownika z którego proces został uruchomiony)
PRI – priorytet procesu w kontekście przestrzeni jądra. Nie możemy zmienić. Zakres jest od 0 do 139.
NI – priorytet użytkownika – zakres od -20 do 19. Gdzie najwyższy priorytet to -20. Ogólnie uznaje się że zwiększenie priorytetu oznacza częstszy przydział czasu procesora do tego procesu. Zmiana NI powoduje zmianę PRI. F7 i F8 w htopie służą odpowiednio do zmniejszania tego parametru i zwiększania.
VIRT/RES/SHR – parametry użycia odpowiednio pamięci wirtualnej, pamięci fizycznej i pamięci dzielonej.
S – status procesu, możliwe wartości:
1 2 3 4 5 | R - aktywnie działa S - spi T - zatrzymany Z - proces zombie D - czeka na dysk |
CPU% i MEM% – procentowe użycie procesora i pamięci.
TIME – ilość czasu procesora przyznana procesowi.
I kilka ciekawostek:
– klikając w kolumny możemy włączyć sortowanie.
– skrót F4 pozwala na filtrowanie listy procesów (np żeby łatwiej wykonać niższe przykłady)
– skrót F3 szuka nam konkretnego procesu
– skrót F5 pokazuje nam widok drzewa procesu – dzięki temu widzimy kto jest ojcem danego procesu
– skrót F9 pozwala zabić proces (a dokładniej wysłać do niego konkretny sygnał)
Czekaj, stop!
Podoba Ci się to co tworzę? Jeśli tak to zapraszam Cię do zapisania się na newsletter:Jeśli to Cię interesuje to zapraszam również na swoje social media.
Jak i do ewentualnego postawienia mi kawy :)
No i w sumie tyle. Teraz pobawmy się tym cudem;)
Przykłady
tutaj uruchomiliśmy program
1 | sleep 100 |
Jeśli odpalimy
1 | sleep 100 |
to nasz proces przejdzie w stan „T” czyli „zatrzymany” (terminated). Jeśli użyjemy polecenia „fg”, czyli przywrócimy zatrzymany proces do działania to status zmieni się na „S”.
Jeśli natomiast uruchomimy taki kawałek kodu:
1 2 3 4 | from subprocess import Popen, PIPE process = Popen(['sleep', '200'], stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() |
to włączając widok drzewiasty (F5) widzimy jaką rodzinę procesów stworzyliśmy:
Jeśli na procesie
1 | python 1.py |
1 2 | [mmazurek@mmazurek ~]$ python 1.py Killed |
Nie oznacza to jednak że zabiliśmy proces potomny – on nadal jest ale w strukturze drzewiastej zmienił miejsce i jest teraz pod procesem „init” – zaszedł proces adopcji osieroconego procesu.
Zmieniając kod naszego programu python’owego na:
1 2 3 4 5 | from subprocess import Popen, PIPE from time import sleep process = Popen(['sleep', '1'], stdout=PIPE, stderr=PIPE) sleep(40) stdout, stderr = process.communicate() |
stworzymy proces
1 | sleep 1 |
I zrzut z htopa:
Status „running” najłatwiej wywołać, może to być np kod:
1 2 3 | i = 0 while i <1000000000: i = i + 1 |
I efekt w htopie:
Napiszmy jeszcze taki kawałek kodu:
1 2 3 4 5 6 7 8 9 10 11 12 | from threading import Thread from time import sleep def func(arg): for i in range(arg): sleep(5) if __name__ == "__main__": thread = Thread(target = func, args = (10, )) thread.start() thread.join() print "all done" |
Czyli nasz proces uruchamia wątek i w nim robi 10 pętli, każda ze sleepem 5s. Program czeka na zakończenie wątku. Efekt w htopie:
różnica z poprzednimi przykładami jest tu jedna – zobacz że to co jest pod
1 | python 1.py |
Jak widać htop to potężny sprzymierzeniec w walce z obciążaniem maszyny jak i elementami które się na owe obciążenie składają – tj procesami.
Mateusz Mazurek