wait()函数
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){ //son printf("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){ //son printf("I'm process child, pid = %d\n", 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\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()获取导致子进程终止的信号的 编码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2018-08-06 1014 Waiting in Line (30)
2018-08-06 1057 Stack (30)