Linux系列之進程管理
- 2022 年 7 月 30 日
- 筆記
前言
進程是正在運行的程式,Linux系統通常有數百個進程同時運行。本文就來介紹下Linux是如何進行進程管理的。
我們可以看到:
- 查看進程(Viewing processes)
- 查找進程(Finding processes)
- 管理進程(Managing processes)
- 進程的優先順序(Prioritizing processes)
- 殺死進程(Killing processes)
- 在後台運行進程(Running processes in the background)
- 調度進程(Scheduling processes)
查看進程
ps
Linux內核在創建進程時,會按順序給每個進程分配一個唯一的進程ID(PID)。一般來說,在進程上執行任何操作,我們必須指定PID,有時我們可以使用名稱。
ps
命令是查看進程的主要工具。不使用任何選項來運行該命令,會列出當前登錄用戶所啟動(調用)的進程,以及終端上正在運行的進程。
如果我們添加了aux
選項:
a
= 顯示所有用戶的進程u
= 顯示進程的用戶/所有者x
= 顯示未連接到終端的進程
進程按照它們被啟動的順序進行展示,因此你會看到列表是根據PID進行排序的。
讓我們簡單來看看下面幾列的資訊:
USER
:調用進程的用戶。PID
:進程的ID。%CPU
:進程佔用CPU的百分比。%MEM
:進程佔用記憶體的百分比。COMMAND
:啟動進程的命令。
查找命令
grep
我們可以使用grep
命令來查找指定的進程,假設我們想要查找所有名稱中包含mfsconsole
的進程。
ps aux | grep msfconsole
top
我們可以使用top
命令來動態地羅列出,按照資源使用情況排序的進程,從最大的開始羅列。默認情況下,該列表將每3秒刷新一次。
top
管理進程
優先順序
內核對進程的優先順序有最終決定權,但是我們可以使用nice
命令,來建議應該提升進程的優先順序。nice
命令的值範圍是從-20(最有可能得到優先權)到+19(最不可能得到優先權)。
較高的nice
值轉換為低優先順序,較低的nice
值轉換為高優先順序。
當一個進程啟動後,所有的標準進程都以nice
值0來進行啟動。
我們可以使用nice
命令來設置一個進程啟動時的nice
值,我們可以使用renice
來調整一個運行中的進程的nice
值。
當我們使用nice
命令啟動一個進程但沒有提供任何值時,默認的nice
值是10。
nice
命令要求你遞增nice
值,renice
命令想要一個絕對的nice
值。
設置優先順序
我們可以使用nice
命令來調整一個程式的nice
值。這允許我們提高或降低內核提供給該進程的優先順序,相對於其他進程而言。
在左邊,我執行watch -n1 free
來展示系統記憶體使用情況的細節。在右邊,我讓top
命令運行,你可以看到watch
命令的PID
是9717,nice
的值為0。
讓我們繼續執行watch
命令,只不過這次是用nice
命令。
nice -15 watch -n1 free
現在我們可以看到watch
的nice
值為15。這裡要牢記的幾件事:
- 這個
watch
命令的PID
與之前的watch
命令不同。這是因為nice
會啟動一個新的進程,而不是更改一個現有的進程。 nice
命令後面的-15
意味著15
。如果我們想要指定一個負數(高優先順序),我們可以使用雙中劃線-
。- 下面是執行
sudo nice --10 watch -n1 free
後的樣子。是的,如果你要提高優先順序,你必須使用sudo
。任何人都可以降低優先順序,但只有sudo
可以提高優先順序。
改變優先順序
renice
命令接收-20
到19
的絕對值,並接收進程的PID
。
讓我們再次運行watch
命令。
watch -n1 free
讓我們來檢查下nice
值,既然我們沒有指定nice
值,它應該為0。比起使用top
,這裡我將會使用ps
和grep
,用以簡化輸出。
我們可以看到,第八列的值為0,該值為nice
的值,PID
的值位於第三列。讓我們使用renice
試試:
sudo renice -15 14318
我們可以看到,現在nice
的值是-15。我們也可以使用top
工具來改變nice
值。
在top
中,按下R
鍵,並提供一個PID
:
按下回車鍵,並提供一個新的nice
值:
top
成功的改變了nice
值:
殺死進程
kill
你可以通過kill
命令來停止一個有問題的進程。kill
命令有64種不同的kill
訊號,以及語法是kill -signal PID
。如果沒有顯示的提供訊號位,將會默認為SIGTERM
。這裡我將重點介紹以下幾種:
訊號名稱 | 數值 | 描述 |
---|---|---|
SIGHUP | 1 | 掛斷(HUP)訊號。它停止指定的進程,並以相同的PID重新啟動它。 |
SIGINIT | 2 | 中斷(INT)訊號。這是一個微弱的kill訊號,不保證能起作用,但確實有這樣的情況。 |
SIGQUIT | 3 | 核心轉儲。終止進程並將進程資訊保存在記憶體中,然後它將這些資訊保存在當前工作目錄下一個名為core的文件中。 |
SIGTERM | 15 | 終止(TERM)訊號。它是kill命令的默認kill訊號。 |
SIGKILL | 9 | 這是一個絕對的kill訊號。它通過將進程的資源發送到一個特殊的設備/dev/null來迫使進程停止。 |
下面的命令會通過HUP訊號來重啟我們的watch
命令。
kill -1 14318
下面的命令會確保進程被終止。
kill -9 16318
如果我們不知道PID
,我們可以使用killall
命令,它接收進程的名稱。
killall -9 watch
在後台運行進程
&
當你執行一個命令時,shell
會進行等待,直到命令完成後才提供另一個命令提示。我們可以在後台運行一個進程,它將繼續運行而不需要終端,把終端騰出來做其他工作。我們在命令的末尾添加&
來做到這一點。
geany sample.txt &
geany
不再佔用整個終端。
fg
我們如何讓它回到前台?可以使用帶有PID的fg
命令。
fg 18345
bg
你也可以使用bg
命令來移動一個進程到後台。
bg 18345
調度進程
在Linux中,我們可以使用at
和crond
來調度進程。crond
有點複雜,這裡重點介紹at
。
at
at
命令對於安排一項工作在未來某個時間點運行一次很有用。它設置了atd
守護進程。守護進程是一個位於後台的程式,在沒有任何用戶介面的情況下做自己的事情。
下面是at
命令執行進程的時間的語法,時間可以以多種格式提供。
時間格式 | 含義 |
---|---|
at 7:20pm | Run at 7:20 PM of current day. |
at 7:20pm June 25 | Run at 7:20 PM on June 25 |
at now + 20 minutes | Run in 20 minutes |
at 7:25pm 06/10/2021 | Run at 7:25 pm on June 10, 2021 |
at noon
我們可以看到,at
將我們帶入了交互模式,在這裡我們輸入了我們希望在指定時間執行的命令。完成後按下CTRL+D。
atq
使用atq
來羅列出所有預定的at
工作。