iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0

系統行程管理

Linux 是個多人多工作業系統,擁有強大的行程資源調度能力。

程式一旦執行後,它們會使用 CPU 運算,記憶體空間、檔案操作或是網路,雖然在一般的維護上我們無法知道程式運作的內部細節,但是可以透過觀察來看哪些行程在之前不曾看過(資訊安全考量)、使用量異常等現象。

查看行程資訊

在 Linux 中,檢查行程最常用的工具可能是 top,他的輸出我們在先前有提到,以下為部份行程列表有關的資訊:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3206 root      20   0  162012   2288   1588 R   0.3  0.0   0:00.13 top
    1 root      20   0  128248   6916   4196 S   0.0  0.0   2:12.10 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:07.21 kthreadd

上述是 top 指令從行程列表開始的資訊,每一行代表一個正在運作的行程,我們可以看到幾個常用欄位:

  1. PID (Process ID):這是行程在作業系統中的唯一識別碼,用來辨識行程的編號。
  2. USER: 知道哪個用戶執行了該行程有助於確定資源使用的責任。也是安全性監控的一個元素。
  3. %CPU 和 %MEM: 這兩個欄位顯示了行程使用的 CPU 和記憶體百分比,是評估系統性能和資源消耗的重要指標。
  4. TIME+: 這個欄位顯示行程自從啟動後使用的總CPU時間。對於長時間運行但消耗資源不多的行程,這個數字可能會很高。
  5. COMMAND: 從這裡可以知道行程是如何啟動的,這在診斷問題或確定是否為惡意軟體時很有用。

top 是一個互動式工具,但有時我們想要得到當下系統所有行程資訊,那麼使用 PS 是更有彈性且清楚列出行程資訊的工具。

ps 加上 aux 參數可以查看系統上所有運行中的行程的詳細信息。這個命令會列出大量的資料,能幫助系統管理員理解行程的運行狀態、資源使用等。

其輸出範例如下:

student$ sudo ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0 190984  3260 ?        Ss   Jan12  59:16 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2  0.0  0.0      0     0 ?        S    Jan12   0:11 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Jan12  52:13 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   Jan12   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S    Jan12   1:37 [migration/0]
root         8  0.0  0.0      0     0 ?        S    Jan12   0:00 [rcu_bh]
root         9  0.0  0.0      0     0 ?        S    Jan12  53:55 [rcu_sched]
root        10  0.0  0.0      0     0 ?        S<   Jan12   0:00 [lru-add-drain]
root        11  0.0  0.0      0     0 ?        S    Jan12   2:57 [watchdog/0]
root        12  0.0  0.0      0     0 ?        S    Jan12   2:44 [watchdog/1]
root        13  0.0  0.0      0     0 ?        S    Jan12   1:45 [migration/1]
... 以下略 ...

以上輸出結果,各欄位為:

  • USER: 行程的所有者或者執行該行程的用戶名。
  • PID: 行程識別碼。
  • %CPU: 正在使用的 CPU 使用率。
  • %MEM: 正在使用的 RAM 使用率。
  • VSZ: 虛擬內存大小(單位為KB)。
  • RSS: Resident Set Size,實際使用的物理內存大小(單位為KB)。
  • TTY: 與行程相關聯的終端類型(如果有的話)。
  • STAT: 行程的狀態。比如,R(運行中)、S(睡眠中)、Z(僵屍)等。
  • START: 行程啟動時的時間。
  • TIME: 到目前為止,該行程消耗的總 CPU 時間。
  • COMMAND: 用於啟動行程的命令。

有時候我們想要瞭解行程的上下關係,那麼可以透過 -f 來查看:

student$ sudo ps auxf
... 以上略 ...
root     15465  0.0  0.0  68092  1628 ?        Ss   00:03   0:00 nginx: master process /usr/sbin/nginx
apache   15466  0.0  0.1  68240  4348 ?        S    00:03   0:00  \_ nginx: worker process
apache   15467  0.0  0.1  68240  4352 ?        S    00:03   0:00  \_ nginx: worker process
... 以下略 ...

以上 ps 部份輸出中,我們可以得知

  • nginx: master process /usr/sbin/nginx 是一個由 root 啟動的主(父)行程。
  • 其下兩個縮排的行程(nginx: worker process)是由父行程建立的子行程,它們是由 apache 用戶運行的。

這樣的檢視方式對於理解行程如何相互關聯特別有幫助。在故障排除或是確認服務(例如,web 伺服器或數據庫服務等)的運行機制是非常有用的。

終止行程

幾乎每個程式都會經歷一個生命週期,執行、運作與結束。除非程式特意設計,否則有時候我們會遇到沒有預期般的結束,這種時候就要透過外部方式把行程關閉,以免造成資源使用過多或繼續執行不該運作的情況。

在 Linux 中,我們可以透過 kill 這個指令來關閉指定的行程,首先我們要先知道幾個項目:

  1. 目標行程 ID: 在 Linux 中每個正在執行的行程都會被指派一個唯一的數字識別碼,可以使用先前介紹的 pstop 找出。
  2. 傳送訊號給目標行程: 當我們找到目標後,要傳送結束的訊號給行程。

kill 指令可以傳送多種訊號給特定的行程,透過 -l 參數可以看到所有可以傳送的訊號:

student$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

雖然在上面的輸出有很多種,但是在一般常使用的訊號為下列幾項:

在 Linux 系統中,使用 kill -l 指令會列出所有可用的訊號(signals)。其中,最常用的大概有以下幾種:

  1. SIGTERM (15) - 這是 kill 指令的預設訊號。當我們送出這個訊號給一個行程時,該行程會收到終止的請求。這個訊號允許行程在結束前有機會釋放資源和進行清理工作。

  2. SIGKILL (9) - 這個訊號會立即終止目標行程,不給予任何清理或釋放資源的機會。因為它是一個強制性的終止,所以一般只在 SIGTERM 無效或需要立即停止行程的情況下使用。

  3. SIGINT (2) - 這個訊號通常是由用戶自己發出的,通過按下 Ctrl+C 讓目標行程終止。

這些訊號各有其用途和特點,選擇哪一個訊號來終止或控制行程需要依據具體需求和該行程的特性。

我們可以透過一個小練習來感受 kill 的做法,先在工作平台上開啟 2 個終端機然後登入。

  • 在第 1 個終端機視窗,輸入 sleep 600 等待 10 分鐘。

  • 在第 2 個終端機,找出 sleep 行程,然後關閉它:

    1. 透過 ps 找出 sleep

      student$ ps aux | grep sleep
      student     25065  0.0  0.0 107952   360 pts/0    S+   13:12   0:00 sleep 600
      

      由上結果所知找到的行程 ID 為 25065

    2. 使用 kill 送出結束訊號:

      student$ kill 25065
      
  • 此時在第 1 個終端機視窗中,應該可以看到執行的行程被中止了。

kill 預設會傳送 SIGTERM(15) 到指定行程中,所以沒有特別指定 kill -15 來傳送。如果行程沒有依我們預期的結束,通常會採用強制手段來中止目標行程,也就是使用 kill -9 的方法,這個方法會有效中止正在運行的行程。


上一篇
Day 16: 系統資源使用情況
下一篇
Day 18: 確保時間準確
系列文
Linux 升華:初學者的探索到專家的洞察30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言