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()获取导致子进程终止的信号的 编码