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

使用waitpid回收多个子进程

使用waitpid回收多个子进程

  • 什么是waitpid
  • 回收多个子进程的方法
    • 方法一:循环调用waitpid
    • 方法二:非阻塞方式回收子进程
    • 方法三:信号处理方式回收子进程
  • 最佳实践和注意事项
  • 总结

在Unix/Linux系统中,创建子进程后,父进程需要负责回收这些子进程的资源,否则会导致"僵尸进程"的产生。本文将详细介绍如何使用waitpid系统调用有效地回收多个子进程。

什么是waitpid

waitpid是Unix/Linux系统提供的一个系统调用,用于等待子进程的状态改变并回收其资源。相比于wait函数,waitpid提供了更灵活的控制选项,可以指定等待哪个特定的子进程,以及是否阻塞等待【1†source】。

#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options);

参数说明:

  • pid: 要等待的子进程ID。特殊值包括:
    • -1: 等待任意子进程
    • 0: 等待与调用进程同组的任意子进程
    • 0: 等待指定PID的子进程

  • status: 用于存储子进程退出状态的指针
  • options: 控制选项,最常用的是WNOHANG,表示非阻塞模式

回收多个子进程的方法

方法一:循环调用waitpid

最简单的方法是在父进程中循环调用waitpid,直到所有子进程都被回收:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {pid_t pids[5];int i;// 创建5个子进程for (i = 0; i < 5; i++) {pids[i] = fork();if (pids[i] == 0) {// 子进程代码printf("Child process %d started\n", getpid());sleep(1 + rand() % 3); // 随机休眠1-3秒printf("Child process %d exiting\n", getpid());exit(0);}}// 父进程回收子进程int status;pid_t pid;for (i = 0; i < 5; i++) {pid = waitpid(pids[i], &status, 0);if (pid == -1) {perror("waitpid");exit(1);}printf("Parent reaped child %d\n", pid);}return 0;
}

方法二:非阻塞方式回收子进程

使用WNOHANG选项,父进程可以在不阻塞的情况下检查子进程状态:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {pid_t pids[5];int i;// 创建5个子进程for (i = 0; i < 5; i++) {pids[i] = fork();if (pids[i] == 0) {// 子进程代码printf("Child process %d started\n", getpid());sleep(1 + rand() % 3); // 随机休眠1-3秒printf("Child process %d exiting\n", getpid());exit(0);}}// 父进程非阻塞方式回收子进程int status;pid_t pid;int children_left = 5;while (children_left > 0) {pid = waitpid(-1, &status, WNOHANG);if (pid > 0) {// 成功回收一个子进程printf("Parent reaped child %d\n", pid);children_left--;} else if (pid == 0) {// 有子进程仍在运行printf("Waiting for children to finish...\n");sleep(1);} else {// 出错perror("waitpid");exit(1);}}printf("All children have been reaped\n");return 0;
}

方法三:信号处理方式回收子进程

可以通过SIGCHLD信号来通知父进程子进程已经终止,然后在信号处理函数中回收子进程:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>void sigchld_handler(int sig) {int status;pid_t pid;// 回收所有已终止的子进程while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {printf("Parent reaped child %d\n", pid);}
}int main() {pid_t pids[5];int i;// 设置SIGCHLD信号处理struct sigaction sa;sa.sa_handler = sigchld_handler;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;if (sigaction(SIGCHLD, &sa, NULL) == -1) {perror("sigaction");exit(1);}// 创建5个子进程for (i = 0; i < 5; i++) {pids[i] = fork();if (pids[i] == 0) {// 子进程代码printf("Child process %d started\n", getpid());sleep(1 + rand() % 3); // 随机休眠1-3秒printf("Child process %d exiting\n", getpid());exit(0);}}// 父进程继续执行其他任务printf("Parent doing other work...\n");sleep(5);printf("Parent finished\n");return 0;
}

最佳实践和注意事项

  1. 及时回收子进程:父进程应该及时回收子进程,避免僵尸进程的产生【2†source】。

  2. 处理异常情况:在调用waitpid时,应该检查返回值,处理可能的错误情况。

  3. 信号处理注意事项:使用信号处理方式回收子进程时,需要注意信号处理函数的可重入性和安全性。

  4. 避免竞争条件:在多线程环境中使用waitpid时,需要注意同步问题,避免竞争条件。

  5. 使用WNOHANG:对于需要同时处理多个任务的父进程,使用WNOHANG选项可以避免阻塞,提高程序的响应性【3†source】。

总结

waitpid是Unix/Linux系统中回收子进程的强大工具,通过合理使用waitpid及其选项,父进程可以有效地管理多个子进程。本文介绍了三种常见的回收多个子进程的方法,包括循环调用、非阻塞方式和信号处理方式,并提供了相应的代码示例。根据具体的应用场景和需求,选择最适合的方法来管理子进程,可以提高程序的健壮性和效率。

在实际开发中,还需要考虑程序的错误处理、资源释放和信号安全等问题,确保程序在各种情况下都能正确运行。

http://www.dtcms.com/a/588881.html

相关文章:

  • leetcode1547.切棍子的最小成本
  • ThinkPHP8学习篇(十一):模型关联(一)
  • 深入理解Ribbon的架构原理
  • 力扣(LeetCode)100题:3.无重复字符的最长子串
  • 前端接口安全与性能优化实战
  • ssh网站怎么做wordpress搬家_后台错乱
  • LangChain V1.0 Messages 详细指南
  • 网站商城微信支付接口申请软件开发人工收费标准
  • 代码生成与开发辅助
  • claude code访问本地部署的MCP服务
  • 学习笔记8
  • Vue编程式路由导航
  • android contentprovider及其查看
  • 根据网站做软件免费网站app下载
  • Rust 练习册 :解开两桶谜题的奥秘
  • 2025.11.03作业 WEB服务
  • Electron 应用中的系统检测方案对比
  • 秦皇岛 网站制作怎么做网站推广临沂
  • oj 数码积和(略难
  • RT-Thread开发实战 --- PIN设备的使用
  • Android的binder机制理解
  • 二十五、STM32的DMA(数据转运)
  • 湖北省建设厅政务公开网站wordpress加速网站插件
  • 提示词(Prompt)工程与推理优化
  • 简析单目相机模型中的针孔模型
  • Apache Flink CDC——变更数据捕获
  • 从“数据堆场”到“智能底座”:TDengine IDMP如何统一数据语言
  • 从细胞工厂到智能制造:Extracellular 用 TDengine 打通数据生命线
  • 哪里有建设网站的html展示wordpress
  • Windows 下编译 WhisperKit Android CLI 的解决方案