軟件b2c網(wǎng)站建設(shè)網(wǎng)頁開發(fā)
1. 進程等待的概念
進程等待是指父進程通過系統(tǒng)調(diào)用wait
或waitpid
來對子進程進行狀態(tài)檢測與回收的功能。
當子進程退出時,如果父進程不讀取子進程的退出狀態(tài),子進程就會成為僵尸進程,造成內(nèi)存泄漏的問題。因此,父進程需要調(diào)用wait
或者waitpid
確認子進程的退出信息以回收僵尸進程的資源以防止內(nèi)存泄漏。
進程等待的必要性
- 回收僵尸進程:子進程退出后,如果父進程不進行處理,子進程會變成僵尸進程,占用系統(tǒng)資源,可能導(dǎo)致內(nèi)存泄漏。
- 獲取子進程的退出情況:父進程可以通過進程等待獲取子進程的退出碼和退出信號,從而了解子進程的執(zhí)行結(jié)果
?2. 進程等待的方法
進程等待通過包含在頭文件<sys/types.h>和<sys/wait.h>中的兩個函數(shù)實現(xiàn):wait()和waitpid()。
wait和waitpid函數(shù)用于等待子進程,等待意味著等待為子進程收尸,父進程可能會在wait或waitpid處阻塞,等待子進程退出。
2.1 wait函數(shù)
pid_t wait(int* status);
- 函數(shù)原型:
pid_t wait(int *status);
- 功能:使調(diào)用的進程(通常是父進程)暫停執(zhí)行,直到一個子進程終止或發(fā)生一個信號。
- 參數(shù):
status
是一個輸出型參數(shù),用于存放子進程的終止狀態(tài),如果不關(guān)心子進程的退出狀態(tài),可以設(shè)置為NULL。
- 返回值:如果有子進程退出,
wait()
返回子進程的PID,并可通過status
指針獲取子進程的退出狀態(tài);如果等待失敗,則返回-1。
?2.2 waitpid函數(shù)
pid_ t waitpid(pid_t pid, int *status, int options);
- 函數(shù)原型:
pid_t waitpid(pid_t pid, int *status, int options);
- 功能:提供更多的控制,允許父進程等待特定的子進程,或者是與父進程有特定關(guān)系的任何子進程。
- 參數(shù):
pid
:指定要等待的子進程的PID;若為-1,則等待任何子進程,與wait
等效。status
:和wait
一樣,用于存放子進程的終止狀態(tài)。options
:可以控制waitpid
的行為,該參數(shù)選擇性傳入,不傳時行為與wait相同。WNOHANG
:如果指定的子進程沒有結(jié)束,waitpid
函數(shù)不會阻塞(進程不會暫停等待子進程結(jié)束),而是立即返回0。WUNTRACED
:返回終止子進程信息和因信號停止的子進程信息。WCONTINUED
:返回收到SIGCONT
信號而恢復(fù)執(zhí)行的已停止子進程狀態(tài)信息
- 返回值:
- 當正常返回的時候,
waitpid
返回收集到的子進程的進程ID。 - 如果設(shè)置了選項
WNOHANG
,而調(diào)用中waitpid
發(fā)現(xiàn)沒有已退出的子進程可收集,則返回0。 - 如果調(diào)用中出錯,則返回-1,這時
errno
會被設(shè)置成相應(yīng)的值以指示錯誤所在。
- 當正常返回的時候,
?2.3 status的用法
*status作為一個整型值,其四個字節(jié)的各個字段分別用于存儲各類信息,我們可以將其看作位圖。
我們并不需要記住哪些字段用于存儲什么信息,如何解析,因為操作系統(tǒng)為我們定義了一系列的宏來對*status進行解析:
WIFEXITED(status)
:
- 功能:檢查子進程是否正常退出。
- 返回值:如果子進程通過調(diào)用
exit
或_exit
正常退出,則返回一個非零值。- 使用示例:
if (WIFEXITED(status)) {printf("子進程正常退出\n"); }
WEXITSTATUS(status)
:
- 功能:獲取子進程的退出狀態(tài)碼。
- 返回值:返回子進程通過
exit
或_exit
系統(tǒng)調(diào)用設(shè)置的退出狀態(tài)碼。- 使用示例:
if (WIFEXITED(status)) {int exit_status = WEXITSTATUS(status);printf("子進程的退出狀態(tài)碼是:%d\n", exit_status); }
WIFSIGNALED(status)
:
- 功能:檢查子進程是否因為接收到信號而異常終止。
- 返回值:如果子進程因為接收到信號而終止,則返回一個非零值。
- 使用示例:
if (WIFSIGNALED(status)) {printf("子進程因為信號而異常終止\n"); }
WTERMSIG(status)
:
- 功能:獲取導(dǎo)致子進程終止的信號編號。
- 返回值:返回導(dǎo)致子進程終止的信號編號。
- 使用示例:
if (WIFSIGNALED(status)) {int signal_number = WTERMSIG(status);printf("導(dǎo)致子進程終止的信號編號是:%d\n", signal_number); }
WIFSTOPPED(status)
:
- 功能:檢查子進程是否因為接收到信號而暫停。
- 返回值:如果子進程因為接收到信號而暫停,則返回一個非零值。
- 使用示例:
if (WIFSTOPPED(status)) {printf("子進程因為信號而暫停\n"); }
WSTOPSIG(status)
:
- 功能:獲取導(dǎo)致子進程暫停的信號編號。
- 返回值:返回導(dǎo)致子進程暫停的信號編號。
- 使用示例:
if (WIFSTOPPED(status)) {int stop_signal = WSTOPSIG(status);printf("導(dǎo)致子進程暫停的信號編號是:%d\n", stop_signal); }