一、進程退出
-
?退出場景?
- ?正常終止?:代碼執行完畢且結果符合預期(退出碼為?
0
)。 - ?異常終止?:運行結果錯誤(退出碼非?
0
)或進程被信號強制終止。(如?SIGINT
?或?SIGSEGV
)。
- ?正常終止?:代碼執行完畢且結果符合預期(退出碼為?
-
?退出方法?
- ?正常退出方式?:
return
:從?main
?函數返回,隱含調用?exit
?函數。exit(int status)
:標準庫函數,執行清理操作(如刷新緩沖區、調用?atexit
?注冊的函數)后終止進程。_exit(int status)
:系統調用,直接終止進程,不刷新緩沖區。? ? ??
- ?正常退出方式?:
exit函數和_exit函數的區別
_exit? :立即終止進程,不執行任何清理操作
exit? ?:? 調用清理函數、刷新緩沖區后終止進程
二、進程等待?
為什么要有進程等待?
父進程在忙,子進程結束了,但無人回收,這樣就造成了“死亡”的子進程一直占用資源
這個時候的子進程被稱為“僵尸進程”
為了解決這個問題,最初的思路是:讓父進程停下,等待子進程執行完,然后回
-
?
- ?回收資源?:子進程退出后若未回收,將殘留?
task_struct
?結構(僵尸進程)。 - ?獲取狀態?:父進程需通過等待機制獲取子進程的退出碼或異常信號。
- ?回收資源?:子進程退出后若未回收,將殘留?
1、wait
?函數參數解析?
pid_t wait(int *status);
參數說明?
- ?
status
?:- 類型為?
int*
,是輸出型參數,用于接收子進程的終止狀態(如退出碼或終止信號)。 - 若不關心子進程狀態,可設為?
NULL
(如?wait(NULL)
)
- 類型為?
返回值?
- 成功時返回終止的子進程 pid;
- 無子進程或調用失敗時返回
2、waitpid
?函數參數詳解?
pid_t waitpid(pid_t pid, int *status, int options);
- ?參數說明?
- ?
pid
?:- ?
> 0
?:等待指定 pid?的子進程; - ?
-1
?:等待任意子進程(等價于?wait
); - ?
0
?:等待與調用進程同進程組的所有子進程; - ?
< -1
?:等待進程組 ID 為?|pid|
?的任意子進程。
- ?
- ?
status
?:- 同?
wait
?的?status
?參數,存儲子進程終止狀態。
- 同?
- ?
options
?:- ?
0
?:默認阻塞模式; - ?
WNOHANG
?:非阻塞模式,若指定子進程未結束則立即返回?0
; - ?
WUNTRACED
?:支持作業控制,返回已暫停的子進程狀態。
- ?
- ?
- ?返回值?
- 成功時返回子進程 pid;
- 若使用?
WNOHANG
?且無子進程終止,返回?0
; - 錯誤時返回?
-1
。
waitpid
?函數第二個參數詳解
waitpid
?函數的第二個參數?int *status
?是用于接收子進程終止狀態的關鍵參數,需配合特定宏解析具體信息。以下是詳細說明:
tatus不能簡單的當作整型來看,要從二進制的角度來看,32位下,整型轉化為二進制有32個bit位,但是我們僅關注低16位
?正常退出?(子進程調用?exit
?或?_exit
):
if (WIFEXITED(status)) { int exit_code = WEXITSTATUS(status); // 提取低8位退出碼(取值范圍0~255):ml-citation{ref="2,4" data="citationList"}
}
?信號終止?(子進程被信號殺死):?
if (WIFSIGNALED(status)) { int signal_num = WTERMSIG(status); // 提取終止信號編號(如 SIGKILL=9):ml-citation{ref="4,7" data="citationList"} printf("Terminated by signal: %d\n", signal_num);
}
?暫停狀態?(需配合?WUNTRACED
?選項):?
if (WIFSTOPPED(status)) { int stop_signal = WSTOPSIG(status); // 提取暫停信號編號(如 SIGSTOP=19):ml-citation{ref="4,7" data="citationList"}
}
status
?的二進制位分布:??
?
?
WIFEXITED(status)
:判斷子進程是否正常退出(返回非零值時表示正常退出)。WEXITSTATUS(status)
:若子進程正常退出,通過此宏獲取子進程的退出碼(如?exit(5)
?中的?5
)。WIFSIGNALED(status)
:判斷子進程是否因信號終止(返回非零值時表示被信號終止)。WTERMSIG(status)
:若子進程因信號終止,通過此宏獲取信號代碼(如?SIGKILL
?對應?9
)
??可忽略性?
若父進程不關心子進程狀態,可將參數設為?NULL
,此時僅等待子進程結束而不獲取狀態信息?
?
關鍵細節?
- ?指針的必要性?:必須傳遞地址(如?
&status
),操作系統需要寫入狀態值到該地址。 - ?狀態位結構?:
status
?的整數值包含多個信息位,需通過宏函數按需提取。 - ?與?
wait
?的關系?:wait(&status)
?等價于?waitpid(-1, &status, 0)
,二者的?status
?解析方式一致
?
?