文章目錄
- 行程創建
- 行程終止
- 行程等待
- 行程替換
行程創建
意義:
行程運行時常會出現崩潰,為了避免父行程出現奔潰,則會創建子行程去代替父行程處理事務,即使崩潰并不會影響到父行程的正常運行,再創建一個子行程再次處理罷了,
用法:(man命令查相關命令及函式的具體用法)

| fork() | 創建子行程,父子行程虛擬地址空間獨立 |
|---|---|
| vfork() | 創建子行程,并阻塞父行程,父子行程同用一塊虛擬地址空間 |
回傳值:子行程回傳0;父行程回傳子行程pid;出錯回傳-1
阻塞父行程:因為子行程和父行程分配到CPU的可能性是一樣的,所以子行程與父行程誰先運行難以確定,但經過阻塞父行程后,子行程便先于父行程獲取到CPU,
為什么要阻塞父行程:因為使用vfork()函式創建子行程時,父子行程共用同一塊虛擬地址空間,因此共用同塊堆疊去,如果不進行阻塞,會出現堆疊混亂的現象,

上一篇文章分析了行程創建的原理,鏈接如下:
https://blog.csdn.net/qq_44768163/article/details/115014661
行程終止
| 方法 | 介面 | 頭檔案 | 區別 |
|---|---|---|---|
| exit | 庫函式呼叫介面 | <stdlib.h> | 退出后重繪緩沖區 |
| _exit | 系統呼叫介面 | <unistd.h> | 退出后并不重繪緩沖區 |
| return | 只能在main中使用 | --------- | 退出后重繪緩沖區 |

具體執行流程如下:
- printf列印的內容讀入緩沖區
- 進入fun函式,退出呼叫該函式的的行程,并重繪緩沖區,輸出------
- 使用echo $? 獲取回傳值99
注:緩沖區的存在避免了頻繁操作輸出設備,使得輸入內容存滿后,再重繪緩沖區,,
行程等待
概念:
父行程等待子行程退出,獲取退出子行程的退出回傳值,釋放子行程資源,避免產生僵尸行程,
方法:

wait方法:(等待任意一個子行程退出)
回傳值:成功- ->回傳被等待行程pid;失敗- ->回傳-1;
引數:獲取子行程退出狀態- ->int *status;不關心子行程退出狀態- ->置為NULL
waitpid方法:(等待任意一個子行程退出或等待一個指定的子行程退出)
回傳值:
當正常回傳的時候waitpid回傳收集到的子行程的行程ID;
如果設定了選項WNOHANG,而呼叫中waitpid發現沒有已退出的子行程可收集,則回傳0;
如果呼叫中出錯,則回傳-1,這時errno會被設定成相應的值以指示錯誤所在;
引數:
pid:
Pid=-1,等待任一個子行程,與wait等效,
Pid>0.等待其行程ID與pid相等的子行程,
status:
WIFEXITED(status): 若為正常終止子行程回傳的狀態,則為真,(用來查看行程是否是正常退出)
WEXITSTATUS(status): 若WIFEXITED非零(正常終止),提取子行程退出碼,(用來查看行程的退出碼)
options:
0:表示默認阻塞等待
WNOHANG: 設定為非阻塞等待
阻塞等待:為了完成一個功能,發起呼叫,若當前不具備完成條件,則一直等待,
非阻塞等待:為了完成一個功能,發起呼叫,若當前不具備完成條件,則報錯回傳,eg:若pid指定的子行程沒有結束,則waitpid()函式回傳0,不予以等待,若正常結束,則回傳該子行程的ID,
實驗:
wait方法

正常退出運行結果:

例外退出運行結果:(使用kill強殺依然屬于正常退出,這里通過不創建子行程再等待即可模擬出等待失敗回傳-1的場景)

waitpid方法:

正常退出:

例外退出:

獲取子行程的status

行程替換
其實有六種以exec開頭的函式,統稱exec函式:
#include <unistd.h>`
int execl(const char *path, const char *arg, …);//庫函式
int execlp(const char *file, const char *arg, …);//庫函式
int execle(const char *path, const char *arg, …,char *const envp[]);//庫函式
int execv(const char *path, char *const argv[]);//庫函式
int execvp(const char *file, char *const argv[]);//庫函式
int execve(const char *path, char *const argv[], char *const envp[]);//系統呼叫函式
引數說明:
第一個引數:新的程式檔案路徑名
第二個引數:程式的運行引數
第三個引數:程式的環境變數
實驗:


總結:
有沒有p的區別:
在于程式檔案是否需要帶路徑,有p時可以不帶路徑,但前提是該程式檔案必須在PATH環境變數指定路徑下,
有沒有e的區別:
在于程式是否自己設定環境變數,有e時自己設定環境變數(覆寫式設定,將之前已有的環境變數覆寫),沒有e時,使用默認已有的環境變數,
l和v的區別:
在于程式運行引數的賦予方式不同,l是一一列舉傳入,v是將運行引數列入陣列中,整體傳入
上圖是行程替換的幾種實作方式,分別對已有的ls程式檔案和自定義實作的arg.c檔案進行了替換實作,結果,,,,,,,,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/271501.html
標籤:其他
上一篇:Linux——行程等待、程式替換
