top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 28961 root 20 0 43816 3148 4040 R 3.2 0.0 0:00.01 top 620 root 20 0 37280 33676 908 D 0.3 0.4 0:00.01 app 1 root 20 0 160072 9416 6752 S 0.0 0.1 0:37.64 systemd 1896 root 20 0 0 0 0 Z 0.0 0.0 0:00.00 devapp 2 root 20 0 0 0 0 S 0.0 0.0 0:00.10 kthreadd 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H 6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq 7 root 20 0 0 0 0 S 0.0 0.0 0:06.37 ksoftirqd/0
向一個進程發送SIGSTOP 信號,它就會因響應這個信號變成暫停狀態(Stopped);再向它發送 SIGCONT 信號,進程又會恢復運行(若是進程是終端裏直接起動的,docker
則須要你用fg命令,回覆到前臺運行)
瀏覽器
而當你的用的調試器調試一個進程是,在使用斷點中斷進程後,進程就會變成跟蹤狀態,這其實也就是一種特殊的暫停狀態,只不過你能夠用調試器
來跟蹤並按需控制進程的運行bash
瞭解了這些,咱們再回到今天的主題,先看不可終端狀態,這實際上是爲了保證進程數據與硬件狀態一直,而且增加狀況下,不可終端狀態在很短期內會結束,服務器
因此短時的不可終端進程咱們通常可忽略微信
但若是系統或硬件發生了故障,進程可能會在不可中斷狀態保持好久,甚至致使系統中出現大量不可中斷進程,這時,你就得注意下,系統時不時出現了I/O 等性能問題。app
再看殭屍進程,這是多進程應用很容易碰到的問題,正常狀況下,當一個進程建立了子進程後,它應該經過系統調用 wait() 或者 waitpid() 等待子進程結束,回收子進程的資源;
而子進程在結束時,會向它的父進程發送SIGCHLD 信號,因此,父進程還能夠註冊 SIGCHLD信號的處理函數,異步回收資源
異步
若是父進程這麼作,或是子進程執行太快,父進程尚未來得及處理子進程狀態,子進程就已經提早退出,那這時的紫禁城就會變成殭屍進程,換句話說,父親應該一直對兒子負責,有始有終,若是不做爲或者跟不上、都會致使"問題少年"的出現函數
一般、殭屍進程持續的時間都比較短,在父進程回收它的資源後就會消亡;或者在父進程推出後,由init進程回收後也會消亡性能
一旦父進程沒有處理子進程的種植,還一直保持運行狀態,那麼子進程就會一直處於殭屍狀態,大量的殭屍進程會用盡PID進程號,
致使新進程不能建立,因此這種狀況必定要避免學習
docker run --privileged --name=app -itd feisky/app:iowait
ps aux | grep /app root 4009 0.0 0.0 4376 1008 pts/0 Ss+ 05:51 0:00 /app root 4287 0.6 0.4 37280 33660 pts/0 D+ 05:54 0:00 /app root 4288 0.6 0.4 37280 33668 pts/0 D+ 05:54 0:00 /app
一、s 和 + 是什麼意思呢?
s 表示這個進程是一個會話的領導進程,而 + 表示前臺進程組
這裏又出現了兩個新概念,進程組和會話,他們用來管理一組相互關聯的進程,意思其實很好理解
二、什麼是進程組?
進程組表示一組相互關聯的進程,好比每一個子進程都是父進程所在組的成員;而會話是隻共享同一個控制終端的一個或多個進程組
三、什麼是會話?
好比,我麼經過SSH登陸服務器,就會打開一個控制終端(TTY),這個控制終端就對應一個會話,而我咱們在終端中運行的命令以及他們的子進程
就構成了一個個的進程組,其中,在後臺運行的命令,構成後臺進程組;在前臺運行的命令,就構成前臺進程組
# 按下數字 1 切換到全部 CPU 的使用狀況,觀察一下子按 Ctrl+C 結束 $ top top - 05:56:23 up 17 days, 16:45, 2 users, load average: 2.00, 1.68, 1.39 Tasks: 247 total, 1 running, 79 sleeping, 0 stopped, 115 zombie %Cpu0 : 0.0 us, 0.7 sy, 0.0 ni, 38.9 id, 60.5 wa, 0.0 hi, 0.0 si, 0.0 st %Cpu1 : 0.0 us, 0.7 sy, 0.0 ni, 4.7 id, 94.6 wa, 0.0 hi, 0.0 si, 0.0 st ... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4340 root 20 0 44676 4048 3432 R 0.3 0.0 0:00.05 top 4345 root 20 0 37280 33624 860 D 0.3 0.0 0:00.01 app 4344 root 20 0 37280 33624 860 D 0.3 0.4 0:00.01 app 1 root 20 0 160072 9416 6752 S 0.0 0.1 0:38.59 systemd ...
從這裏你能看出什麼問題嗎?逐行觀察,別放過任何一個地方,忘了哪行參數意思的話,也要及時返回去複習
先看第一行平均負載,過去一、五、15分鐘內的平均負載依次減少,說明平均負載正在升高,而1分鐘內的平均負載已經達到了系統CPU的個數,說明系統可能已經有了性能瓶頸
Tasks 有1個正在運行的進程,但殭屍進程比較多,並且還在不停增長,說明有子進程在退出時沒有沒清理
CPU使用率:用戶CPU和系統CPU都不高,但iowait分別是60.5%和94.6%好像有點不正常
每一個進程的狀況:CPU使用率最高的進程只有0.3%,看起來並不高;可是有兩個進程處於D狀態,它們可能在等待I/O,但光憑這裏並不能肯定是它們致使了 iowait 升高
咱們把這四個問題在彙總一下,就能夠獲得很明確的兩點:
第一點:iowait過高了,致使系統的平均負載生該,甚至達到系統CPU的個數
第二點:殭屍進程在不斷增多,說明程序沒能正確清理子進程的資源
老師說多是案例裏I/O線程還不夠多,效果不明顯,等着老師修改案例從新發鏡像,再實驗。
在和老師屢次交流下,終於逼得老師發佈一個把本身機器跑死的鏡像,就能夠了,結果和老師的溫和了。
[root@luoahong ~]# docker run --privileged --name=app -itd feisky/app:iowait-new2 Unable to find image 'feisky/app:iowait-new2' locally iowait-new2: Pulling from feisky/app 32802c0cfa4d: Already exists da1315cffa03: Already exists fa83472a3562: Already exists f85999a86bef: Already exists f69cb5280862: Pull complete Digest: sha256:9fc8b013aff0bc2c1b1dc41a33989a8ddd4ed7da56f53f6559bbc76836041dc2 Status: Downloaded newer image for feisky/app:iowait-new2 00ed5564248127a98c467eb99f8b32d3dc3ebc5d7f47563d6617ccfd7348b10b [root@luoahong ~]# ps aux | grep /app root 11798 0.1 0.0 4368 380 pts/0 Ss+ 09:54 0:00 /app root 11851 0.0 0.8 70040 65776 pts/0 R+ 09:55 0:00 /app root 11852 0.0 0.8 70040 65776 pts/0 R+ 09:55 0:00 /app root 11854 0.0 0.0 112708 980 pts/0 S+ 09:55 0:00 grep --color=auto /app
top截圖
執行這個鏡像,iowait打滿,直接把個人微信給擠掉了,瀏覽器都打不開了,不過結果是好的。
用我麼最熟悉的ps或者top,能夠直接查看進程的狀態,這些狀態包括運行(R)、空閒(I)、不可中斷睡眠(D)、可中斷睡眠(S)、殭屍(Z)以及暫停(T)等
其中,不可中斷狀態和殭屍狀態,是咱們今天學習的重點
不可中斷狀態:表示進程正在跟硬件交互,爲了保護進程數據和硬件的一致性,系統不容許其餘進程或中斷打斷這個進程。進程長時間處於不可中斷狀態,一般標識系統有I/O 性能問題
殭屍進程表示進程已經退出,但它的父進程尚未回收子進程佔用資源。短暫的殭屍狀態咱們一般沒必要理會,但進程長時間屬於殭屍狀態,
就應該注意了,可能有應用程序沒有正常處理子進程退出