wait()函數:回收僵尸進程
父進程調用wait函數可以回收子進程終止信息。該函數有三個功能:
1) 阻塞等待子進程退出
2) 回收子進程殘留資源
3) 獲取子進程結束狀態(退出原因)
/*** zoom_test.c ***/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h>int main(void) {pid_t pid, wpid;pid = fork();int status;if (pid == 0) {printf("---child, my parent= %d, going to sleep 10s\n", getppid());sleep(20);printf("-------------child die--------------\n");exit(77);} else if (pid > 0) {while (1) {printf("I am parent, pid = %d, myson = %d\n", getpid(), pid);wpid = wait(&status);if (wpid == -1) {perror("wait error");exit(1);}if (WIFEXITED(status)) { //為真說明子進程正常結束printf("child exit with %d\n", WEXITSTATUS(status));} else if (WIFSIGNALED(status)) { //為真說明子進程被信號終止(異常)printf("child is killed by %d\n", WTERMSIG(status));}sleep(1);}} else {perror("fork");return 1;}return 0; }
pid_t wit(int *status); 成功:清理掉的子進程ID;失敗:-1(沒有子進程)
當進程終止時,操作系統的隱式回收進制會:
- 關閉所有的文件描述符;
- 釋放用戶空間的內存;
內核的PCB仍存在。其中保存該進程的退出狀態。(正常終止—>推出值;異常退出—>終止信號)
可使用wait函數傳出參數status來保存進程的退出狀態。借助宏函數來進一步判斷進程終止的具體原因。宏函數可以分為以下三組:
- WIFEXITED(status) 為非0 à 進程正常結束
WEXITSTATUS(status)如上宏為真,使用此宏à獲取進程的退出狀態(exit參數) - WIFSIGNALED(status)為非0 à 進程異常終止
WTERMSIG(status)如上宏為真,使用此宏 à 取得使進程終止的那個信號的編號
/*** wait1.c ***/ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/wait.h>int main(void) {pid_t pid, wpid;pid = fork();if(pid == -1){perror("fork error");exit(1);} else if(pid == 0){ //sonprintf("I'm process child, pid = %d\n", getpid());sleep(7); //困了...} else { lable:wpid = wait(NULL); //死等!!!if(wpid == -1){perror("wait error");goto lable;}printf("I'm parent, I catched child process,""pid = %d\n", wpid);}return 0; }
/*** wait2.c ***/ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/wait.h>int main(void) {pid_t pid, wpid;int status;pid = fork();if(pid == -1){perror("fork error");exit(1);} else if(pid == 0){ //sonprintf("I'm process child, pid = %d\n", getpid()); #if 1execl("./abnor", "abnor", NULL);perror("execl error");exit(1); #endifsleep(1); exit(10);} else {//wpid = wait(NULL); //傳出參數wpid = wait(&status); //傳出參數if(WIFEXITED(status)){ //正常退出printf("I'm parent, The child process ""%d exit normally\n", wpid);printf("return value:%d\n", WEXITSTATUS(status));} else if (WIFSIGNALED(status)) { //異常退出printf("The child process exit abnormally, ""killed by signal %d\n", WTERMSIG(status));//獲取信號編號} else {printf("other...\n");}}return 0; }
wait(status):
???????????????????? 返回:成功:pid? 失敗 -1
???????????????????? status:傳出參數
???????????????????? 1: 阻塞等待子進程
???????????????????? 2: 回收子進程資源
???????????????????? 3:??? 獲取子進程結束狀態:1)WIFEXITED()真
????????????????????????????????????????????????????????????????????? WEXITSTATUS()獲取子進程退出狀態
?????????????????????????????????????????????????????????????? 2)WIFSIGNALED() 真
????????????????????????????????????????????????????????????????????? WTERMSIG()獲取導致子進程終止的信號的?????????????????????????????????????????????????????????????????????????????????????????? 編碼
?