当前位置: 首页 > news >正文

⏳ waitpid() 函数解析

📜 函数原型

pid_t waitpid(pid_t pid, int *status, int options);

🔑 参数详解

  1. pid: 要等待的子进程 PID,可以指定特定的进程或进程组。

    • > 0: 等待特定 PID 的子进程。

    • -1: 等待任意子进程(行为类似 wait())。

    • 0: 等待与调用进程同一进程组的任意子进程。

    • < -1: 等待特定进程组的子进程。

  2. status: 子进程状态的输出,可以通过宏(如 WIFEXITED, WEXITSTATUS)来解析。

  3. options: 控制等待行为的选项(可组合)。

    • WNOHANG: 非阻塞模式,若没有子进程退出,立即返回 0

    • WUNTRACED: 报告已停止的子进程状态。

    • WCONTINUED(Linux 特有):报告已恢复的子进程状态。


💡 返回值

  • 成功: 返回子进程的 PID。

  • 失败: 返回 -1,并设置 errno(常见错误:ECHILD 无子进程,EINTR 被信号中断)。

  • 非阻塞模式(WNOHANG: 若无子进程退出,返回 0


🧐 状态解析宏

通过 status 参数获取子进程的退出原因:

  1. 正常退出:

    • WIFEXITED(status):若为真,表示子进程正常退出。

    • WEXITSTATUS(status):获取子进程的退出码。

  2. 被信号终止:

    • WIFSIGNALED(status):若为真,表示子进程被信号终止。

    • WTERMSIG(status):获取导致终止的信号编号。

  3. 被信号暂停(需 WUNTRACED 选项):

    • WIFSTOPPED(status):若为真,表示子进程被暂停。

    • WSTOPSIG(status):获取导致暂停的信号编号。

  4. 恢复执行(需 WCONTINUED 选项):

    • WIFCONTINUED(status):若为真,表示子进程从暂停状态恢复。


⚡ 典型用法

1. 阻塞等待特定子进程
pid_t child_pid = fork();
if (child_pid == 0) {
    // 子进程代码
    exit(42);  // 子进程正常退出
} else {
    int status;
    pid_t ret = waitpid(child_pid, &status, 0);  // 等待特定子进程
    if (ret == child_pid) {
        if (WIFEXITED(status)) {
            printf("Child exited with code %d\n", WEXITSTATUS(status)); // 输出 42
        }
    }
}
2. 非阻塞轮询子进程状态
int status;
pid_t ret;
while ((ret = waitpid(-1, &status, WNOHANG)) > 0) {  // 非阻塞模式
    // 处理已退出的子进程
}
if (ret == 0) {
    // 没有子进程退出,继续执行其他任务 💼
} else if (ret == -1) {
    // 错误处理 🛑
}
3. 处理被信号终止的子进程
if (WIFSIGNALED(status)) {
    printf("Child killed by signal %d 💥\n", WTERMSIG(status));
}

📝 注意事项

  1. 僵尸进程: 如果父进程没有调用 waitpid(),子进程将变成僵尸进程(Zombie),占用系统资源 ⚠️。

  2. 信号处理: 在 SIGCHLD 信号处理函数中调用 waitpid() 可以及时回收子进程 🛠️。

  3. 多线程安全: 在多线程环境中使用时需谨慎,以避免竞争条件 ⚔️。

  4. 错误处理: 在出现错误时需要检查 errno,区分不同的错误类型 ❗。


🤔 wait() vs waitpid()

特性wait()waitpid()
目标子进程任意子进程可指定 PID 或进程组
阻塞行为总是阻塞支持非阻塞(WNOHANG 选项)
扩展状态信息不支持支持(如 WUNTRACED

🌐 总结

通过 waitpid(),开发者可以精确地控制子进程的等待行为,适用于需要管理多个子进程或者非阻塞式进程监控的场景。掌握它就像拥有了监控多任务的神奇能力 🧙‍♂️。

相关文章:

  • Windows11,微软软件(VSCODE/EDG)错误登录,0x80190001错误
  • 小了 60,500 倍,但更强;AI 的“深度诅咒”
  • DeepSeek技术架构解析:MLA多头潜在注意力
  • 汽车诊断开发入门以及OBD检测
  • 【学Rust写CAD】21 2D 点(point.rs)
  • Vue中将pdf文件转为图片
  • LabVIEW永磁同步电机性能测试系统
  • MyBatis--#{}和${}
  • 人脸表情识别数据集的正确使用方法(Affectnet、RAF-DB、FERPlus数据集通用)
  • 树莓派超全系列教程文档--(20)树莓派配置自动息屏
  • VINS-Mono学习(六):回环检测
  • react antd 项目报错Warning: Each child in a list should have a unique “key“prop
  • Python入门(5):异常
  • Dart 实现与蓝牙设备的通信
  • JSON 基础知识(一)
  • 碰一碰发视频系统--基于H5场景开发
  • 【一起来学kubernetes】32、kubectl使用详解
  • 视频分析设备平台EasyCVR安消一体化解决方案,打造社区/园区全面可视化智能安消应用
  • HNSW(Hierarchical Navigable Small World,分层可导航小世界)用来高效搜索高维向量的最近邻
  • JAVA常见的 JVM 参数及其典型默认值
  • 上海这场有温度的“人才集市”,为更多人才搭建“暖心桥”
  • 经济日报:人工智能开启太空经济新格局
  • 南京艺术学院博导、雕塑家尹悟铭病逝,年仅45岁
  • 价格周报|本周猪价继续下探,机构预计今年猪价中枢有支撑
  • 公示资费套餐、规范营销行为,今年信息通信行业将办好这十件实事
  • 高瓴、景林旗下公司美股持仓揭晓:双双增持中概股