Linux程序
Linux程序
程序是程式的動態表現, 是分配資源(記憶體、時間片)的基本單位
Linux下程序結構:搶親緣關係(父子程序)
PCB控制塊:
程序pid、程序狀態、程序啟動時長等
PCB中記錄了作業系統所需的,用於描述程序的當前情況以及控制程序執行的全部資訊。
程序建立過程
0~3G:使用者空間
3G~4G:PCB
1. 父程序呼叫fork, 核心建立子程序_CREAT
2. 核心用父程序的PCB控制塊進行子程序PCB的初始化(除了pid等程序唯一資訊)
3. 核心將父程序的使用者空間拷貝給子程序(讀時共享, 寫時複製)
4. 子程序從fork之後開始執行
fork
系統內建未經過包裹的API
fork();
返回值:
父程序中返回子程序的pid
在子程序中返回0
-1表示失敗
pid連續的程序具有親緣關係(層級關係)
vfork:建立不繼承父程序使用者空間的子程序, 需要配合exec使用
區分父子程序的工作
通過fork的返回值區分父子程序
if (fork() > 0) { // 父程序工作 } else if (fork() == 0) { // 子程序工作 } else { // fork出錯 }
獲取程序ID
pid_t getpid(void); // 獲取當前程序id
pid_t getppid(void); // 獲取當前程序父程序id
EXEC族
完成程序功能過載
將其他程序的使用者空間拷貝到當前程序, 如果還有其他工作, 需要在fork和exec之間完成
execl("/bin/ls", "-l", NULL);
還有其他exec族函式
殭屍程序(Zombie)
子程序先於父程序終止
核心不會釋放所有子程序的資源, PCB不會被回收(為了讓父程序瞭解子程序終止的資訊)
系統PCB的數量是有限的, 如果沒有回收乾淨, 可能無法建立新的程序
父程序回收子程序PCB資源
wait:
pid_t wait(int *status); // 引數:子程序終止原因
wait函式是阻塞函式, 回收成功返回子程序的pid
如果沒有子程序, 呼叫失敗, 返回-1, errno被置為ECHILD。
WIFEXITED(int status); // 判斷是否是正常終止
WEXITSTATUS(int status); // 如果正常終止, 獲取return返回值
WIFSIGNALED(int status); // 判斷程序是否是被訊號殺死
STERMSIG(int statux); // 獲取殺死程序的訊號編號
...
waitpid:
pid_t waitpid(pid_t pid, int *status, int option);
引數:
pid < -1:回收指定組中的所有子程序(組號)
pid == -1:回收所有子程序
pid == 0:回收同組的所有子程序
pid > 0:回收指定的一個子程序(程序ID)
status:程序終止資訊
option:WNOHANG和WUNTRACED
WNOHANG:不會一直等待子程序結束, 立即返回
WUNTRACED:
返回值:
成功返回回收的子程序pid
子程序不需要回收:0
沒有子程序:-1
孤兒程序
父程序先於子程序結束