一、函数概述
1. 函数原型与头文件
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *wstatus);2. 返回值
成功:返回已终止子进程的PID。
失败:返回-1,当前进程无子进程时,错误码置为
ECHILD。
3. 核心功能
阻塞父进程,等待当前进程创建的任意子进程终止。
回收终止子进程的PCB残留资源,清除僵尸进程,避免系统PID资源耗尽。
获取并保存子进程的完整退出状态,包含退出码、终止信号等信息。
4. 使用前置条件
wait()函数仅用于回收当前进程通过fork()创建的子进程。
未创建子进程时直接调用该函数,会直接调用失败。
二、wstatus参数底层存储机制
子进程退出后,内核将其退出状态信息按二进制位打包存储于wstatus指向的整型内存空间,不同比特位对应不同状态信息,无法直接通过变量原值读取有效数据。
比特位分布规则
0~7 bit:存储子进程终止信号编号,子进程正常退出时该数据为0。
8~15 bit:存储子进程退出码,仅占用8位存储空间。
退出码取值规则
受8位存储空间限制,子进程退出码有效取值范围为0~255。若传入数值超出范围,系统自动对256取模。
exit(256)等效exit(0)exit(257)等效exit(1)exit(300)等效exit(44)
三、wstatus两种传参方式及完整实现
方式一:传参 &wstatus(保存子进程退出状态)
使用说明
自定义整型变量int wstatus,将变量地址传入函数。该方式可保存子进程完整退出状态,支持两种合法解析方式:手动位运算解析、系统标准宏解析。两种方式功能等价,适用场景不同。
1. 手动位运算解析(底层原理实现)
依据比特位分布规则,通过移位、按位与运算直接解析状态数据,无需依赖系统宏,仅适配Linux平台,用于理解底层存储原理。
核心解析公式:
提取退出码:
(wstatus >> 8) & 0xff提取终止信号:
wstatus & 0x7f
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main(void) { pid_t pid = fork(); if(pid == 0) { exit(10); } int wstatus; wait(&wstatus); // 位运算解析退出状态 int exit_code = (wstatus >> 8) & 0xff; //int sig_num = wstatus & 0x7f; printf("子进程退出码:%d\n", exit_code); //printf("子进程终止信号:%d\n", sig_num); return 0; }2. 系统宏解析(工程标准实现)
调用系统封装的状态解析宏,跨平台兼容性强,是工程开发的标准写法。
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main(void) { pid_t pid = fork(); if(pid == 0) { exit(10); } int wstatus; wait(&wstatus); if(WIFEXITED(wstatus)) { printf("子进程正常退出,退出码:%d\n", WEXITSTATUS(wstatus)); } //else if(WIFSIGNALED(wstatus)) //{ // printf("子进程被信号终止,信号编号:%d\n", WTERMSIG(wstatus)); //} return 0; }方式二:传参 NULL(仅回收僵尸进程)
使用场景
仅需清除子进程僵尸状态、释放系统资源,无需获取子进程退出码、终止信号等状态信息。
使用说明
无需定义状态变量,无需状态解析操作,代码简洁,仅完成进程回收功能。
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main(void) { pid_t pid = fork(); if(pid == 0) { printf("子进程执行完毕\n"); exit(5); } wait(NULL); printf("父进程完成子进程资源回收\n"); return 0; }四、两种解析方式对比
解析方式 | 合法性 | 兼容性 | 适用场景 |
|---|---|---|---|
手动位运算解析 | 合法有效 | 仅Linux平台适配 | 底层原理学习、知识点验证 |
系统宏解析 | 标准合法 | 全UNIX/Linux平台通用 | 工程项目开发、正式业务代码 |
五、系统状态解析宏说明
系统宏为内核封装的跨平台状态解析接口,仅适用于wait(&wstatus)传参场景。
宏定义 | 功能描述 | 使用条件 |
|---|---|---|
WIFEXITED(wstatus) | 判断子进程是否为正常退出 | 任意场景 |
WEXITSTATUS(wstatus) | 提取子进程正常退出码 | 子进程正常退出 |
WIFSIGNALED(wstatus) | 判断子进程是否被信号终止 | 任意场景 |
WTERMSIG(wstatus) | 获取终止子进程的信号编号 | 子进程被信号终止 |
六、核心总结
wait()函数依赖fork()创建的子进程,无有效子进程时调用失败,函数具备阻塞特性。
wait(&wstatus)用于保存子进程退出状态,支持手动位运算和系统宏两种解析方式,功能等价、场景不同。wait(NULL)仅用于回收僵尸进程,舍弃所有退出状态信息,适用于无需判断子进程执行结果的场景。子进程退出码仅占用8位存储空间,有效范围0~255,超出数值自动对256取模。
手动位运算用于底层原理学习,工程开发统一使用系统宏,保障代码跨平台兼容性。