程序管理

pro111發表於2024-10-26

程序管理

同步和非同步

同步(Synchronous)

  1. 定義
    • 在同步操作中,任務執行的順序是固定的,後一個任務必須等待前一個任務完成後才能開始。
  2. 特點
    • 阻塞:在同步操作中,呼叫者會被阻塞,直到操作完成。這意味著程式會在當前任務上停留,無法執行其他任務。
    • 易於理解:因為執行順序是線性的,容易跟蹤和除錯。

非同步(Asynchronous)

  1. 定義

    • 在非同步操作中,任務的執行不依賴於其他任務的完成,呼叫者可以在發起請求後繼續執行其他操作。
  2. 特點

    • 非阻塞:呼叫者不會被阻塞,可以繼續執行其他程式碼。通常會使用回撥函式或事件機制來處理結果。
    • 更高的效率:可以在等待 I/O 操作(如網路請求或檔案讀取)時執行其他計算任務,提高資源利用率。
    
    

ps

[root@localhost ~]# ps aux|more
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
USER:擁有該程序的使用者。
PID:程序 ID。
%CPU:CPU 使用百分比。
%MEM:記憶體使用百分比。
VSZ:虛擬記憶體大小。
RSS:常駐記憶體集大小(實際使用的記憶體)。
TTY:與程序關聯的終端。
STAT:程序狀態。
START:程序開始時間。
TIME:總 CPU 時間使用量。
COMMAND:啟動該程序的命令
ps aux --sort=-%mem|more 按照記憶體排序
ps aux --sort=-%cpu|more 按照cpu排序

pmap

用於顯示程序的記憶體對映情況。它可以提供指定程序的虛擬記憶體使用情況,包括各個記憶體段的地址、大小、許可權等資訊。

pmap <PID>

top

top - 07:04:59 up  8:04,  2 users,  load average: 0.00, 0.00, 0.00
Tasks: 220 total,   1 running, 219 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.0 us,  3.0 sy,  0.0 ni, 93.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3710.0 total,   2610.7 free,    607.3 used,    491.9 buff/cache
MiB Swap:   4032.0 total,   4032.0 free,      0.0 used.   2868.0 avail Mem 

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND       

系統摘要資訊

  • 07:04:59:當前時間。
  • up 8:04:系統已經執行了 8 小時 4 分鐘。
  • 2 users:當前有 2 個使用者登入。
  • load average: 0.00, 0.00, 0.00:系統的負載平均值,分別是最近 1 分鐘、5 分鐘和 15 分鐘的負載。0.00 表示系統負載非常低。

任務資訊

  • Tasks: 220 total:總共有 220 個程序。
  • 1 running:當前有 1 個程序正在執行。
  • 219 sleeping:有 219 個程序處於休眠狀態。
  • 0 stopped:沒有停止的程序。
  • 0 zombie:沒有殭屍程序。

CPU 使用情況

  • %Cpu(s)

    :CPU 使用的詳細資訊:

    • 3.0 us:使用者程序佔用的 CPU 百分比(使用者空間)

      表示使用者空間(user space)程序佔用的 CPU 百分比。這些程序是由使用者啟動的,不涉及核心的直接管理。高使用者空間 CPU 使用率通常表明使用者應用程式正在積極執行。
      
    • 3.0 sy:系統程序佔用的 CPU 百分比(核心空間)。

      表示核心空間(system space)程序佔用的 CPU 百分比。核心程序是作業系統核心元件,負責管理系統資源(如檔案系統、程序管理等)。較高的系統 CPU 使用率可能表示系統正處理大量的 I/O 操作或其他核心級任務。
      
    • 0.0 ni:使用者程序以非負優先順序執行佔用的 CPU 百分比。

      表示以非負優先順序(nice value 大於或等於 0)執行的使用者程序佔用的 CPU 百分比。`nice` 值是用來調整程序的優先順序,較高的 `nice` 值意味著較低的優先順序。此值為 0 表示沒有程序在以非負優先順序執行。
      
    • 93.9 id:空閒的 CPU 百分比。

    • 0.0 wa:等待 I/O 的 CPU 百分比。

      表示等待 I/O 操作的 CPU 百分比。這個值表明 CPU 有多少時間在等待 I/O 操作(如磁碟讀寫)完成。較高的 I/O 等待時間可能表示磁碟或網路 I/O 是瓶頸。
      
    • 0.0 hi0.0 si0.0 st:分別表示硬體中斷、軟體中斷和虛擬機器偷取的 CPU 百分比。

      1.硬體中斷是來自硬體裝置(如鍵盤、滑鼠、網路等)的訊號,CPU 需要暫時停止當前的任務去處理這些訊號。
      
      當你按下鍵盤上的某個鍵時,鍵盤硬體會生成一箇中斷訊號,通知 CPU 有新的輸入
      CPU 接收到這個中斷訊號後,會暫停當前正在執行的任務,儲存其狀態,然後轉到鍵盤中斷處理程式(Interrupt Service Routine, ISR)。
      處理程式會讀取按下的鍵的程式碼(通常稱為掃描碼),並將其傳遞給作業系統。
      處理完成後,CPU 會恢復之前的任務,繼續執行。
      
      2.軟體中斷通常由作業系統內部產生,用於處理特定的任務或請求。
      
      程式呼叫 read():
      假設一個程式需要從檔案中讀取資料,它會執行類似於 bytes_read = read(file_descriptor, buffer, size); 的程式碼。這行程式碼實際上請求作業系統來執行讀取操作。
      生成軟體中斷:
      當程式執行到這條指令時,它會觸發一個軟體中斷(通常是透過特定的指令,如 int 0x80 在舊的 Linux 系統中,或使用系統呼叫的庫函式在現代系統中)。
      作業系統接收到軟體中斷後,會暫停當前程式的執行,並儲存其上下文(例如暫存器狀態)。
      作業系統的核心會找到與 read() 系統呼叫相對應的處理程式。這通常是一個核心級的函式,負責處理檔案讀取請求。
      核心中的 read() 處理程式會執行實際的讀取操作。這可能涉及從磁碟或其他儲存裝置獲取資料。
      資料被讀取到指定的緩衝區中。
      讀取完成後,核心會把讀取到的位元組數返回給使用者程式。
      隨後,核心會恢復使用者程式的執行狀態,將控制權返回給它,程式可以繼續執行接下來的程式碼。
      
      3.在虛擬化環境中,主機的虛擬機器可能會“偷取”某些 CPU 資源。如果這個值很高,可能表示主機資源不足,影響了虛擬機器的效能。
      
      

記憶體使用情況

  • MiB Mem:記憶體的詳細資訊:
    • 3710.0 total:總記憶體為 3710 MB。
    • 2610.7 free:當前可用記憶體為 2610.7 MB。
    • 607.3 used:已使用記憶體為 607.3 MB。
    • 491.9 buff/cache:用於緩衝區和快取的記憶體。
  • MiB Swap:交換空間的詳細資訊:
    • 4032.0 total:總交換空間為 4032 MB。
    • 4032.0 free:當前可用的交換空間為 4032 MB(表示沒有使用交換空間)。
    • 0.0 used:已使用的交換空間為 0 MB。
    • 2868.0 avail Mem:可用記憶體(包括緩衝區和快取的記憶體)為 2868 MB。

程序資訊

  • PID:程序 ID。
  • USER:擁有該程序的使用者。
  • PR:程序優先順序。
  • NI:程序的 nice 值。
  • VIRT:程序使用的虛擬記憶體。
  • RES:程序使用的常駐記憶體。
  • SHR:程序共享的記憶體。
  • S:程序狀態(例如 R 表示執行中,S 表示睡眠)。
  • %CPU:程序使用的 CPU 百分比。
  • %MEM:程序使用的記憶體百分比。
  • TIME+:程序使用的總 CPU 時間。
  • COMMAND:啟動程序的命令。

load average

負載值的定義

  • 在 Linux 系統中,負載值表示在特定時間段內,正在執行或等待執行的程序的數量。它不僅包括正在使用 CPU 的程序,還包括那些等待 CPU 資源的程序。

負載值的取值範圍

  • 負載值是一個非負數,理論上沒有上限,但負載過高通常會導致系統效能下降。

負載值的具體解釋

  • 小於 1
    • 說明系統負載輕,CPU 資源充足。此時,平均每個 CPU 核心都有足夠的時間來處理其任務。例如,在一個單核心繫統中,負載為 0.5 表示 CPU 只有一半的時間被佔用,還有一半的時間是空閒的。
  • 等於 1
    • 系統負載達到了其能力的邊界。每個執行的程序都能在適當的時間內獲得 CPU 資源,但沒有冗餘的處理能力。此時,使用者可能會感受到效能的波動。
  • 大於 1(以單核 CPU 為例)
    • 如果負載大於 1,表示有多個程序在爭奪 CPU 資源。例如,負載為 2 表示有兩個程序在等待 CPU 資源,這可能會導致某些程序的響應時間增加。
    • 舉例:在單核系統中,負載為 2 意味著系統正在處理的任務數量是 CPU 能夠處理的兩倍,因此會有一部分任務在等待,這可能導致系統變慢。
  • 多核 CPU 的影響
    • 在多核系統中,負載值需要結合 CPU 核心數量進行評估。例如,在一個 4 核 CPU 系統中:
      • 負載值為 4 表示系統處於滿負荷狀態,但 CPU 仍然可以處理所有任務。
      • 負載值為 5 表示有一個任務在等待,可能會影響效能。
      • 負載值為 8 則表示有很多程序在等待 CPU 資源,系統可能變得非常緩慢。

瞬時高負載:短時間內的高負載(如 10-15 秒)可能是正常的,尤其是在進行大量計算或I/O操作時,但如果持續存在,應該考慮進行效能最佳化或資源擴充套件。

殭屍程序

(Zombie Process)是指已經完成執行但仍然存在於程序表中的程序。它的狀態是“殭屍”,因為它的父程序尚未讀取它的退出狀態資訊

殭屍程序的形成

  1. 程序生命週期

    • 當一個程序執行完畢後,它會傳送一個退出狀態給其父程序。這一狀態包含了程序的執行結果和資源使用情況。
    • 此時,程序不會立即從程序表中刪除,而是變為殭屍狀態,等待父程序使用 wait()waitpid() 函式讀取退出狀態。

    父程序未處理

    • 如果父程序沒有在子程序結束後呼叫 wait(),那麼子程序會保持在殭屍狀態,繼續佔用一個程序表項。

殭屍程序的特徵

  • 狀態:殭屍程序的狀態一般會顯示為 Z,表示它是一個殭屍狀態。
  • 資源佔用:殭屍程序不佔用 CPU 資源,因為它已經完成了執行,但仍然佔用一個程序表項。
  • 父程序:殭屍程序依賴於其父程序來清理。如果父程序終止而沒有收集子程序的資訊,這些殭屍程序會被 init(程序 ID 為 1 的程序)收養,init 會定期清理這些殭屍程序。

殭屍程序的影響

  • 程序表佔用:儘管殭屍程序不消耗 CPU 資源,但它們仍然佔用程序表中的條目。系統的程序表有大小限制,如果有過多的殭屍程序,可能導致無法建立新程序。
  • 系統穩定性:在某些情況下,殭屍程序可能會表明程式設計上的缺陷,導致系統不穩定

解決方法

  • 終止父程序:如果殭屍程序的父程序存在,可以透過重啟或修復父程序的程式碼,使其呼叫 wait(),從而清理殭屍程序。
  • 殺死父程序:如果父程序無法處理,可以殺死父程序,此時系統會將殭屍程序交給 init 程序,後者會清理它們。

dd if

dd if=<輸入檔案> of=<輸出檔案> [其他選項]
bs=<位元組數>:設定塊大小,指定每次讀取和寫入的位元組數。
count=<塊數>:指定要複製的塊的數量。

複製檔案

將檔案 input.txt 複製到 output.txt

dd if=input.txt of=output.txt

建立一個空檔案

建立一個大小為 1MB 的空檔案:

dd if=/dev/zero of=empty_file bs=1M count=1

從磁碟建立映象

將整個磁碟 /dev/sda 備份到映象檔案 disk.img

dd if=/dev/sda of=disk.img bs=4M

恢復磁碟映象

將之前建立的映象 disk.img 恢復到磁碟 /dev/sda

dd if=disk.img of=/dev/sda bs=4M

顯示進度

在複製過程中顯示進度資訊:

dd if=input.txt of=output.txt status=progress

訊號管理機制

pid

查詢程式的 PID

pidof bash

查詢所有與 python 相關的程序:

pidof -c python

使用 ps 命令結合 -u 選項可以檢視特定使用者的程序。

ps -u <使用者名稱>

使用 pgrep-G 選項可以根據組名查詢程序:

pgrep -G <組名>

kill

kill 是一個用於傳送訊號給程序的命令列工具,常用於終止或管理正在執行的程序。儘管名稱是 "kill",它不僅可以用來結束程序,還可以用於其他目的,例如暫停程序、繼續執行等。

kill [選項] <程序ID>

-s <訊號> 或 --signal <訊號>:指定要傳送的訊號。預設情況下,kill 傳送 SIGTERM(訊號 15)。
-l:列出所有可用的訊號及其名稱。
-n <訊號編號>:根據訊號編號傳送訊號。例如,kill -n 9 <PID> 傳送 SIGKILL 訊號。
-p:只列印程序的 PID,而不傳送訊號。
訊號名 訊號編號 描述
SIGTERM 15 請求終止程序(預設訊號)。
SIGKILL 9 強制終止程序,無法被捕獲或忽略。
SIGINT 2 中斷程序,通常是 Ctrl+C 傳送給前臺程序。
SIGSTOP 19 暫停程序,無法被捕獲或忽略。
SIGCONT 18 繼續一個被暫停的程序。
SIGHUP 1 通常用於通知程序其控制終端已關閉。

kill 命令通常需要 PID。如果要透過程序名殺死程序,可以結合 pkill 命令:

pkill process_name

程序優先順序

[root@localhost ~]# ps -axo comm,user,nice|more
檢視程序優先順序

改變程序優先順序

使用者建立程序優先順序都為0
系統程序優先順序都為-20
數字越小優先順序越高
renice 10 pid  將已經執行的程序優先順序改為10
nice -n -15 vim /tmp/passwd 將程序優先順序設定為-15(未執行)

job任務控制

/test.sh & 將一個程序放入後臺執行
ctrl +z 將前臺任務暫停
fg %任務號 將後臺程序恢復到前臺
bg %任務號 用於將一個已停止的程序(通常是前臺程序)放到後臺繼續執行。