### PPID
每個進程除了一定有PID還會有PPID,也就是父進程ID,通過PPID可以找到父進程的信息。
為什么進程都會有父進程ID呢?因為進程都是由父進程衍生出來的,后面會詳細介紹幾種衍生的方法。那么跟人類起源問題一樣,父進程的父進程的父進程又是什么呢?實際上有一個PID為1的進程是由內核創建的init進程,其他子進程都是由它衍生出來,所以前面的描述并不準確,進程號為1的進程并沒有PPID。
因為所有進程都來自于一個進程,所以Linux的進程模型也叫做進程樹。
### 示例程序
要想獲得進程的PPID,可以通過以下`Getppid()`這個函數來獲得,print_ppid.go程序的代碼如下。
~~~
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Getppid())
}
~~~
### 運行結果
~~~
root@87096bf68cb2:/go/src# go run print_ppid.go
2892
root@87096bf68cb2:/go/src# go run print_ppid.go
2902
~~~
有趣的事情發生了,有沒有發現每次運行的父進程ID都不一樣,這不符合我們的預期啊,原來我們通過`go run`每次都會啟動一個新的Go虛擬機來執行進程。
### 編譯后運行
如果我們先生成二進制文件再執行結果會怎樣呢?
~~~
root@87096bf68cb2:/go/src# ./print_ppid
1
root@87096bf68cb2:/go/src# ./print_ppid
1
root@87096bf68cb2:/go/src# ps aux |grep "1" |grep -v "ps" |grep -v "grep"
root 1 0.0 0.3 20228 3184 ? Ss 07:25 0:00 /bin/bash
~~~
這次我們發現父進程ID都是一樣的了,而且通過`ps`命令可以看到父進程就是`bash`,說明通過終端執行命令其實是從`bash`這個進程衍生出各種子進程。
為了執行這個程序要查找包依賴、編譯、打包、鏈接(和`go build`做一樣的東西)然后執行,這是全新的進程。
拿到PID和PPID后有什么用呢?馬上揭曉。
- 前言
- 致謝
- 概述
- 使用代碼
- 使用Docker
- 進程基礎
- 進程是什么
- Hello World
- PID
- PPID
- 使用PID
- 進程名字
- 進程參數
- 輸入與輸出
- 并發與并行
- 進程越多越好
- 進程狀態
- 退出碼
- 進程資源
- 死鎖
- 活鎖
- POSIX
- Nohup
- 運行進程
- Go編程實例
- 衍生新進程
- 執行外部程序
- 復制進程
- 進程進階
- 文件鎖
- 孤兒進程
- 僵尸進程
- 守護進程
- 進程間通信
- 信號
- Linux系統調用
- 文件描述符
- Epoll
- 共享內存
- Copy On Write
- Cgroups
- Namespaces
- 項目實例Run
- 項目架構
- 代碼實現
- 注意事項
- 創建目錄權限
- 捕獲SIGKILL
- Sendfile系統調用
- 后記
- 參考書籍
- 項目學習
- 再次感謝