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 ", getppid()); sleep(20); printf("-------------child die-------------- "); exit(77); } else if (pid > 0) { while (1) { printf("I am parent, pid = %d, myson = %d ", getpid(), pid); wpid = wait(&status); if (wpid == -1) { perror("wait error"); exit(1); } if (WIFEXITED(status)) { //为真说明子进程正常结束 printf("child exit with %d ", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { //为真说明子进程被信号终止(异常) printf("child is killed by %d ", 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){ //son printf("I'm process child, pid = %d ", 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 ", 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){ //son printf("I'm process child, pid = %d ", getpid()); #if 1 execl("./abnor", "abnor", NULL); perror("execl error"); exit(1); #endif sleep(1); exit(10); } else { //wpid = wait(NULL); //传出参数 wpid = wait(&status); //传出参数 if(WIFEXITED(status)){ //正常退出 printf("I'm parent, The child process " "%d exit normally ", wpid); printf("return value:%d ", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { //异常退出 printf("The child process exit abnormally, " "killed by signal %d ", WTERMSIG(status)); //获取信号编号 } else { printf("other... "); } } return 0; }
wait(status):
返回:成功:pid 失败 -1
status:传出参数
1: 阻塞等待子进程
2: 回收子进程资源
3: 获取子进程结束状态:1)WIFEXITED()真
WEXITSTATUS()获取子进程退出状态
2)WIFSIGNALED() 真
WTERMSIG()获取导致子进程终止的信号的 编码