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 = 顯示未連接到終端的進程

image.png

進程按照它們被啟動的順序進行展示,因此你會看到列表是根據PID進行排序的。

讓我們簡單來看看下面幾列的資訊:

  • USER:調用進程的用戶。
  • PID:進程的ID。
  • %CPU:進程佔用CPU的百分比。
  • %MEM:進程佔用記憶體的百分比。
  • COMMAND:啟動進程的命令。

查找命令

grep

我們可以使用grep命令來查找指定的進程,假設我們想要查找所有名稱中包含mfsconsole的進程。

ps aux | grep msfconsole

image.png

top

我們可以使用top命令來動態地羅列出,按照資源使用情況排序的進程,從最大的開始羅列。默認情況下,該列表將每3秒刷新一次。

top

image.png

管理進程

優先順序

內核對進程的優先順序有最終決定權,但是我們可以使用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。

image.png

讓我們繼續執行watch命令,只不過這次是用nice命令。

nice -15 watch -n1 free

image.png

現在我們可以看到watchnice值為15。這裡要牢記的幾件事:

  • 這個watch命令的PID與之前的watch命令不同。這是因為nice會啟動一個新的進程,而不是更改一個現有的進程。
  • nice命令後面的-15意味著15。如果我們想要指定一個負數(高優先順序),我們可以使用雙中劃線-
  • 下面是執行sudo nice --10 watch -n1 free後的樣子。是的,如果你要提高優先順序,你必須使用sudo。任何人都可以降低優先順序,但只有sudo可以提高優先順序。

image.png

改變優先順序

renice命令接收-2019的絕對值,並接收進程的PID

讓我們再次運行watch命令。

watch -n1 free

讓我們來檢查下nice值,既然我們沒有指定nice值,它應該為0。比起使用top,這裡我將會使用psgrep,用以簡化輸出。

image.png

我們可以看到,第八列的值為0,該值為nice的值,PID的值位於第三列。讓我們使用renice試試:

sudo renice -15 14318

image.png

我們可以看到,現在nice的值是-15。我們也可以使用top工具來改變nice值。

top中,按下R鍵,並提供一個PID

image.png

按下回車鍵,並提供一個新的nice值:

image.png

top成功的改變了nice值:

image.png

殺死進程

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

image.png

在後台運行進程

&

當你執行一個命令時,shell會進行等待,直到命令完成後才提供另一個命令提示。我們可以在後台運行一個進程,它將繼續運行而不需要終端,把終端騰出來做其他工作。我們在命令的末尾添加&來做到這一點。

geany sample.txt &

image.png

geany不再佔用整個終端。

fg

我們如何讓它回到前台?可以使用帶有PID的fg命令。

fg 18345

bg

你也可以使用bg命令來移動一個進程到後台。

bg 18345

調度進程

在Linux中,我們可以使用atcrond來調度進程。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

image.png

我們可以看到,at將我們帶入了交互模式,在這裡我們輸入了我們希望在指定時間執行的命令。完成後按下CTRL+D。

atq

使用atq來羅列出所有預定的at工作。

image.png