行程與行程控制

行程識別碼(PID)與父行程識別碼(PPID)

當數十個行程同時在執行時,作業系統需要一種方式來區分它們——給每一個一個名牌。那個名牌就是行程識別碼,也就是 PID:核心在每個行程被建立時發給它的一個小正整數。PID 1 很特別(它是最初的那個行程,init),其餘的各自拿到唯一的號碼。當你想對一個行程做事——查看它、停掉它、等它——你就用它的 PID 來指稱它。

每個行程也都記得是誰建立了它。行程是從其他行程誕生的(透過 fork),所以每個都有一個父行程,並把父行程的 PID 存成自己的 PPID,也就是父行程識別碼。這正是讓行程構成一棵樹、而非一張平坦清單的原因:你 shell 的 PID,就是你從它啟動的每個指令的 PPID。行程可以用 getpid() 向核心要自己的 PID,用 getppid() 要父行程的。PID 大致依遞增順序分配,最終會環繞回頭,在一個行程消失並被回收後被重複使用,所以 PID 只在現存行程之間唯一,並非永遠唯一。

為何重要:PID 是你從外部對行程所做幾乎一切事情的把手——等它、發信號給它、在 /proc 裡查它。PPID 則讓核心能替孤兒行程重新指定父行程,也讓工具能畫出行程樹。一個微妙的陷阱:因為 PID 在行程死後會被重複使用,抓著一個舊 PID 還假設它仍指同一個行程,是個實實在在的錯誤——那個號碼現在可能已屬於一個完全不同、更新的行程。

在 shell 裡,執行 echo $$ 印出 shell 自己的 PID,假設是 4021。啟動 sleep 100 &,它可能拿到 PID 4099、PPID 4021——它知道 shell 是它的父行程。執行 ps -o pid,ppid,comm,你就能看到子行程指回 shell。

子行程儲存父行程的 PID,把兩者連進行程樹中。

PID 只在當前存活的行程之間唯一。一個行程被回收後,它的號碼可以被回收再用,所以把 PID 快取起來、之後還信任它,可能悄悄指到另一個行程——只要這件事要緊,就務必重新確認。

又称
PIDPPIDprocess ID行程編號