Ⅰ linux裡面什麼是僵屍進程
僵屍進程是當子進程比父進程先結束,而父進程又沒有回收子進程,釋放子進程佔用的資源,此時子進程都將成為一個僵屍進程。如果父進程先退出,子進程被init接管,子進程退出後init會收回其佔用的相關資源。
我們都知道進程的工作原理。我們啟動一個程序,開始我們的任務,然後等任務結束了,我們就停止這個進程。進程停止後,該進程就會從進程表中移除。
你可以通過System-Monitor查看當前進程。
In UNIX System terminology, a process that has terminated,but whose parent
has not yet waited for it, is called a
zombie.在Unix系統中,一個進程結束了,但是它的父進程沒有等待它,那麼它將變成一個僵屍進程。但是如果該進程的父進程已經先結束了,那麼該進程就不會變僵屍進程,因為每個進程結束的時候,系統都會掃描當前系統中所運行的所有進程,看有沒有哪個進程是剛剛結束的這個進程的子進程,如果是的話,就由init來接管他,成為他的父進程。
怎麼查看僵屍進程?
利用命令ps,可以看到有父進程ID為1的進程是孤兒進程;s狀態為z的是僵屍進程。
注意:孤兒進程是尚未終止但已停止的進程,但其父進程已經終止,由init收養;而僵屍進程則是已終止的進程,其父進程不一定終止。
Ⅱ 如何找到並終止 Linux 系統中的僵屍進程
在了解僵屍進程之前,讓我們來復習一下什麼是 Linux 進程。
簡而言之, 進程 [1] 是一個程序的運行實例。它可能運行在前端(比如有交互的進程),也可能運行在後端(比如無交互或自動運行的進程)。它可能是一個父進程(運行期間創建了其他進程),也可能是一個子進程(由其他進程所創建)。
在 Linux 系統中,除 PID 為 0 的第一個 init 進程(或 systemd )外,其餘進程都有父進程。進程也可以擁有自己的子進程。
不相信?可以試試在終端中使用 pstree 命令查看進程的樹型結構,你能看到系統各個進程的「家族樹」。
子進程死亡後,它的父進程會接收到通知去執行一些清理操作,如釋放內存之類。然而,若父進程並未察覺到子進程死亡,子進程就會進入到「<ruby style="box-sizing: border-box;">僵屍<rt style="box-sizing: border-box;">zombie</rt></ruby>」狀態。從父進程角度看,子進程仍然存在,即使子進程實際上已經死亡。這就是「<ruby style="box-sizing: border-box;">僵屍進程<rt style="box-sizing: border-box;">zombie process</rt></ruby>」(也被稱為「<ruby style="box-sizing: border-box;">已消失進程<rt style="box-sizing: border-box;">defunct process</rt></ruby>」)是如何產生並存在於系統中的。
這里有一個來自 Turnoff.us [2] 的關於僵屍進程的非常有趣的看法:
Image credit: Turnoff.us
重點要說的是,僵屍進程並沒有像它的名稱那樣看起來可怕。
但如果系統的內存已經所剩不多或者有太多的僵屍進程在吃掉內存,問題會變得糟糕。同樣,大部分 Linux 系統進程最大 PID 設置為 32768,如果過多僵屍進程導致其他重要任務沒有 PID 可用,你的系統會發生崩潰。
這是真實可能發生的,它有一定的概率,特別當存在一個編碼糟糕的程序開始大量產生僵屍進程的時候。
在這種情況下,找到並殺死僵屍進程是一個明智的做法。
Linux 系統中的進程可能處於如下狀態中的一種:
那如何查看進程和它的當前狀態呢?一個簡單的方法是在終端中使用 top 命令 [3]。
Top command show processes and their status
正如你在上面截圖中看到的,截圖中共有 250 個任務(進程),其中 1 個處在 「<ruby style="box-sizing: border-box;">運行中<rt style="box-sizing: border-box;">running</rt></ruby>」 狀態,248 個進程處於 「<ruby style="box-sizing: border-box;">休眠<rt style="box-sizing: border-box;">sleep</rt></ruby>」 狀態,還有一個處於 「<ruby style="box-sizing: border-box;">僵屍<rt style="box-sizing: border-box;">zombie</rt></ruby>」 狀態。
現在問題進入下一步,如何殺死 「僵屍」 進程?
僵屍進程已經死了,要如何才能殺死一個已經死亡的進程呢?
在僵屍電影中,你可以射擊僵屍的頭部或燒掉它們,但在這里是行不通的。你可以一把火燒了系統來殺死僵屍進程,但這並不是一個可行的方案。
一些人建議發送 SIGCHLD 給父進程,但這個信號很可能會被忽略。還有一個方法是殺死父進程來殺死僵屍進程,這聽起來很野蠻,但它卻是唯一能確保殺死僵屍進程的方法。
首先,通過在終端中 使用 ps 命令 [4] 我們列舉僵屍進程,得到它們的進程 ID:
<pre class="prettyprint linenums" style="box-sizing: border-box; overflow: hidden; font: 400 12px / 20px "courier new"; display: block; padding: 10px 15px; margin: 20px 0px; color: rgb(248, 248, 212); word-break: break-all; overflow-wrap: break-word; background: rgb(39, 40, 34); border: none; border-radius: 4px; box-shadow: rgb(57, 56, 46) 40px 0px 0px inset, rgb(70, 71, 65) 41px 0px 0px inset; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
</pre>
ps ux 命令輸出的第 8 列顯示了進程狀態。上述命令只會列印所有處在 Z+ 狀態(表示僵屍狀態)的進程。
確認了進程 ID 後,我們可以得到它的父進程 ID:
<pre class="prettyprint linenums" style="box-sizing: border-box; overflow: hidden; font: 400 12px / 20px "courier new"; display: block; padding: 10px 15px; margin: 20px 0px; color: rgb(248, 248, 212); word-break: break-all; overflow-wrap: break-word; background: rgb(39, 40, 34); border: none; border-radius: 4px; box-shadow: rgb(57, 56, 46) 40px 0px 0px inset, rgb(70, 71, 65) 41px 0px 0px inset; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
</pre>
你也可以將上述兩個命令結合在一起,直接得到僵屍進程的 PID 及其父進程的 PID:
<pre class="prettyprint linenums" style="box-sizing: border-box; overflow: hidden; font: 400 12px / 20px "courier new"; display: block; padding: 10px 15px; margin: 20px 0px; color: rgb(248, 248, 212); word-break: break-all; overflow-wrap: break-word; background: rgb(39, 40, 34); border: none; border-radius: 4px; box-shadow: rgb(57, 56, 46) 40px 0px 0px inset, rgb(70, 71, 65) 41px 0px 0px inset; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
</pre>
現在你得到了父進程 ID,使用命令行和得到的 ID 號 終於可以殺死進程了 [5]:
<pre class="prettyprint linenums" style="box-sizing: border-box; overflow: hidden; font: 400 12px / 20px "courier new"; display: block; padding: 10px 15px; margin: 20px 0px; color: rgb(248, 248, 212); word-break: break-all; overflow-wrap: break-word; background: rgb(39, 40, 34); border: none; border-radius: 4px; box-shadow: rgb(57, 56, 46) 40px 0px 0px inset, rgb(70, 71, 65) 41px 0px 0px inset; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
</pre>
Killing parent process
再次運行 ps 命令或 top 命令,你可以驗證僵屍進程是否已經被殺死。
恭喜!現在你知道怎麼清理僵屍進程了。
via: https://itsfoss.com/kill-zombie-process-linux/
Ⅲ linux中查看進程命令ps aux和ps -ef
Linux下顯示系統進程的命令ps,最常用的有ps -ef 和ps aux。這兩個到底有什麼區別呢?兩者沒太大差別,討論這個問題,要追溯到Unix系統中的兩種風格,System V風格和BSD 風格,ps aux最初用到Unix Style中,而ps -ef被用在System V Style中,兩者輸出略有不同。現在的大部分Linux系統都是可以同時使用這兩種方式的。
ps -ef 是用標準的格式顯示進程的、其格式如下:
其中各列的內容意思如下
UID //用戶ID、但輸出的是用戶名
PID //進程的ID
PPID //父進程ID
C //進程佔用CPU的百分比
STIME //進程啟動到現在的時間
TTY //該進程在那個終端上運行,若與終端無關,則顯示? 若為pts/0等,則表示由網路連接主機進程。
CMD //命令的名稱和參數
ps aux 是用BSD的格式來顯示、其格式如下:
同ps -ef 不同的有列有
USER //用戶名
%CPU //進程佔用的CPU百分比
%MEM //佔用內存的百分比
VSZ //該進程使用的虛擬內存量(KB)
RSS //該進程佔用的固定內存量(KB)(駐留中頁的數量)
STAT //進程的狀態
START //該進程被觸發啟動時間
TIME //該進程實際使用CPU運行的時間
其中STAT狀態位常見的狀態字元有
D //無法中斷的休眠狀態(通常 IO 的進程); uninterruptible sleep (usually IO)不可中斷
R //正在運行可中在隊列中可過行的;
S //處於休眠狀態;
T //停止或被追蹤; traced or stopped
W //進入內存交換 (從內核2.6開始無效);
X //死掉的進程 (基本很少見);
Z //僵屍進程; a defunct (」zombie」) process
< //優先順序高的進程
N //優先順序較低的進程
L //有些頁被鎖進內存;
s //進程的領導者(在它之下有子進程);
l //多線程,克隆線程(使用 CLONE_THREAD, 類似 NPTL pthreads);
+ //位於後台的進程組;