一文詳解Linux如何關(guān)閉關(guān)不掉的進(jìn)程
你一定遇到過這種情況:kill -9 都?xì)⒉凰?,進(jìn)程像釘子一樣扎在系統(tǒng)里。這篇文章講清楚原因和所有能用的手段。
一、先搞清楚:為什么關(guān)不掉?
不是所有"關(guān)不掉"都是同一種情況。用 ps aux | grep 進(jìn)程名 看一眼 STAT 列:
| 狀態(tài) | 含義 | 能否被殺死 |
|---|---|---|
| R | 運(yùn)行中 | ? 正常殺 |
| S | 可中斷睡眠 | ? kill -9 可殺 |
| D | 不可中斷睡眠 | ? kill -9 無效 |
| Z | 僵尸進(jìn)程 | ? 已死,只是沒人收尸 |
| T | 被調(diào)試暫停 | ? 殺掉調(diào)試器即可 |
最常見的兩種"殺不死":
- D 狀態(tài):進(jìn)程在等 I/O(讀寫磁盤/網(wǎng)絡(luò)),內(nèi)核不允許被信號(hào)打斷
- Z 狀態(tài):進(jìn)程已退出,但父進(jìn)程沒調(diào)用
wait(),它就一直掛在進(jìn)程表里
二、按場(chǎng)景逐個(gè)擊破
場(chǎng)景 1:kill -9 無效(D 狀態(tài))
這是最棘手的。進(jìn)程卡在內(nèi)核態(tài),信號(hào)根本送不進(jìn)去。
手段一:找到它在等什么,然后解決根源
# 查看進(jìn)程在等什么文件/設(shè)備 lsof -p <PID> # 或者 cat /proc/<PID>/stack
如果是在等 NFS 掛載點(diǎn),那就去恢復(fù) NFS 連接;如果是在等磁盤 I/O,檢查磁盤是否故障。
手段二:強(qiáng)制卸載文件系統(tǒng)
如果進(jìn)程卡在某個(gè)掛載點(diǎn)上:
umount -f -l /mnt/problem # 懶卸載,立刻解除掛載
-l(lazy):立刻把掛載點(diǎn)從文件系統(tǒng)層級(jí)中移除,等進(jìn)程釋放后再真正清理。
手段三:重啟系統(tǒng)(兜底)
實(shí)在沒辦法,這是唯一 100% 有效的方式。
reboot -f # 強(qiáng)制重啟,不走正常關(guān)機(jī)流程
場(chǎng)景 2:僵尸進(jìn)程(Z 狀態(tài))
僵尸進(jìn)程已經(jīng)死了,kill 對(duì)它沒有任何意義——你殺不死一個(gè)已經(jīng)死了的東西。
正確做法:殺它的父進(jìn)程,讓 init(PID 1)接管并回收。
ps -o ppid= -p <僵尸PID> # 查父進(jìn)程 PID kill -9 <父進(jìn)程PID> # 殺父進(jìn)程
殺完之后僵尸進(jìn)程會(huì)自動(dòng)消失。
如果父進(jìn)程是 init(PPID=1),說明 init 沒來得及回收。這種情況:
- 少量僵尸:不用管,系統(tǒng)會(huì)自動(dòng)清理
- 大量僵尸:說明父進(jìn)程有 bug,需要修復(fù)程序本身
場(chǎng)景 3:進(jìn)程被保護(hù)(PID 1 / systemd 子女)
有些進(jìn)程的父進(jìn)程是 1 號(hào)進(jìn)程(systemd),你殺它,systemd 會(huì)立刻重啟。
# 查看父進(jìn)程 pstree -p <PID>
正確做法:讓 systemd 來管
systemctl stop <服務(wù)名> # 正常停止 systemctl disable <服務(wù)名> # 禁止開機(jī)自啟 systemctl mask <服務(wù)名> # 徹底屏蔽,連手動(dòng)啟動(dòng)都不行
場(chǎng)景 4:內(nèi)核線程(名字帶 [])
[kworker/0:1] [migration/0] [ksoftirqd/0]
這些不是用戶進(jìn)程,是內(nèi)核線程,不能殺,也不該殺。殺了會(huì)導(dǎo)致內(nèi)核 panic。
如果你看到某個(gè)內(nèi)核線程 CPU 占用異常高,那是內(nèi)核 bug 或驅(qū)動(dòng)問題,需要排查內(nèi)核日志:
dmesg | tail -50
三、一張表總結(jié)所有手段
| 情況 | 首選方案 | 備選方案 | 終極方案 |
|---|---|---|---|
| D 狀態(tài)(等 I/O) | 找原因,解決 I/O 阻塞 | umount -f -l | reboot -f |
| Z 狀態(tài)(僵尸) | kill 父進(jìn)程 | 等系統(tǒng)自動(dòng)回收 | — |
| 被 systemd 保護(hù) | systemctl stop/mask | — | — |
| 內(nèi)核線程 | 不要?jiǎng)?/strong> | 查 dmesg | — |
| 普通進(jìn)程 | kill -9 | pkill -9 | reboot -f |
四、一個(gè)真實(shí)案例
某天服務(wù)器上一個(gè) Java 進(jìn)程卡死,kill -9 無反應(yīng):
$ ps aux | grep java root 12345 99.0 ... D ... $ lsof -p 12345 java 12345 root 3r REG 8,1 ... /mnt/nfs/data/app.log (deleted)
真相:進(jìn)程在往一個(gè)已經(jīng)被刪除的 NFS 文件寫日志,NFS 服務(wù)器已斷連,進(jìn)程卡在 D 狀態(tài)。
解決:
umount -f -l /mnt/nfs # 懶卸載 NFS # 2 秒后,進(jìn)程自動(dòng)退出
沒有重啟,沒有數(shù)據(jù)丟失,30 秒解決。
寫在最后
"關(guān)不掉的進(jìn)程"本質(zhì)上不是進(jìn)程的問題,是它在等的那個(gè)東西出了問題。
kill -9 是最后的手段,不是第一反應(yīng)。先看狀態(tài),再看它在等什么,絕大多數(shù)情況根本不需要重啟。
以上就是一文詳解Linux如何關(guān)閉關(guān)不掉的進(jìn)程的詳細(xì)內(nèi)容,更多關(guān)于Linux關(guān)閉關(guān)不掉的進(jìn)程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
linux實(shí)現(xiàn)自動(dòng)刪除最舊的幾個(gè)文件詳解
最近因?yàn)楣ぷ鞯脑?,有需求要?jiǎng)h除Linux中舊的壓縮包,發(fā)現(xiàn)網(wǎng)上給的答案都是刪除N天前的文件,無法適應(yīng)我的要求,于是自己研究了一翻。所以下面這篇文章主要介紹了關(guān)于linux自動(dòng)刪除最舊的幾個(gè)文件的相關(guān)資料,需要的朋友可以參考下。2017-09-09
有效學(xué)習(xí)Linux系統(tǒng)的4個(gè)方法
這篇文章主要為大家詳細(xì)介紹了有效學(xué)習(xí)Linux系統(tǒng)的4個(gè)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Windows系統(tǒng)下Apache服務(wù)器無法啟動(dòng)的問題解決
這篇文章主要介紹了Windows系統(tǒng)下Apache服務(wù)器無法啟動(dòng)的問題解決,大多數(shù)情況下還是端口被占用的問題,需要的朋友可以參考下2015-07-07
linux下PAC正向代理某個(gè)網(wǎng)址上網(wǎng)方式
文章描述了在私有化場(chǎng)景下部署Kubernetes服務(wù),并通過內(nèi)部代理服務(wù)器訪問互聯(lián)網(wǎng)的解決方案,通過創(chuàng)建一個(gè)PAC文件的Pod,文章展示了如何配置環(huán)境變量并驗(yàn)證代理服務(wù)器是否正常工作2026-03-03
如何解決Ubuntu18.04循環(huán)登錄/卡在開機(jī)界面/無法進(jìn)入圖形界面的問題
這篇文章主要介紹了如何解決Ubuntu18.04循環(huán)登錄/卡在開機(jī)界面/無法進(jìn)入圖形界面的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
linux系統(tǒng)下使用tcpdump進(jìn)行抓包方法
在本篇文章中小編給大家分享了關(guān)于linux系統(tǒng)下使用tcpdump進(jìn)行抓包的方法和相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-04-04

