Movatterモバイル変換


[0]ホーム

URL:


waitpid函数

原创已于 2025-08-11 15:48:08 修改·823 阅读
· 22
· 6·
CC 4.0 BY-SA版权
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
文章标签:

#linux#操作系统

于 2025-07-22 17:46:38 首次发布

waitpid 系统调用

1. 函数原型与基本语义

#include<sys/types.h>#include<sys/wait.h>pid_twaitpid(pid_t pid,int*wstatus,int options);

1.1 参数解析

参数类型有效取值语义描述
pidpid_t>0等待指定进程ID的子进程
-1等待任意子进程(等效于wait
0等待与调用进程同进程组的任意子进程
<-1等待进程组ID等于pid绝对值的任意子进程
wstatusint *非NULL指针用于存储子进程终止状态的缓冲区地址
NULL不捕获终止状态
optionsintWNOHANG非阻塞模式,立即返回
WUNTRACED同时报告已停止的子进程
WCONTINUED报告已继续执行的被停止子进程
位或组合支持选项的组合使用

2. 返回值处理规范

2.1 成功返回情况

if((child_pid=waitpid(-1,&status, WNOHANG))>0){if(WIFEXITED(status)){log("Child %d exited, status=%d",             child_pid,WEXITSTATUS(status));}elseif(WIFSIGNALED(status)){log("Child %d killed by signal %d%s",             child_pid,WTERMSIG(status),WCOREDUMP(status)?" (core dumped)":"");}// 其他状态判断分支...}

返回值处理应遵循以下逻辑:

  1. 返回值 > 0:成功回收的子进程PID

    • 需通过宏检查wstatus
      • WIFEXITED(status):正常终止
      • WEXITSTATUS(status):获取退出码
      • WIFSIGNALED(status):信号终止
      • WTERMSIG(status):终止信号编号
      • WCOREDUMP(status):是否生成core文件
      • WIFSTOPPED(status):进程停止
      • WSTOPSIG(status):停止信号编号
      • WIFCONTINUED(status):进程继续执行
  2. 返回值 == 0(仅WNOHANG时)

    • 表示存在符合要求的子进程,但尚未终止
    • 需后续轮询或结合信号机制处理
  3. 返回值 == -1:错误发生

    • 需检查errno
      • ECHILD:无匹配子进程
      • EINTR:被信号中断

3. 应用场景

3.1 精确回收特定子进程

pid_t worker_pid=fork();if(worker_pid==0){// 子进程执行任务execv("/path/to/worker", argv);}// 父进程仅等待特定workerint status;if(waitpid(worker_pid,&status,0)==-1){perror("waitpid failed");}

3.2 非阻塞轮询机制

while(1){pid_t pid=waitpid(-1,&status, WNOHANG);if(pid>0){handle_child_exit(pid, status);}elseif(pid==0){usleep(100000);// 100ms延迟continue;}else{if(errno== ECHILD)break;handle_error();}}

3.3 进程组管理

// 创建进程组pid_t pgid=fork();if(pgid==0){setpgid(0,0);// 启动进程组成员...}// 等待整个进程组终止while(waitpid(-pgid,NULL,0)!=-1|| errno!= ECHILD){// 循环直到进程组完全退出}

4. 使用要点

4.1 与信号机制的协同

// 正确设置SIGCHLD处理程序structsigaction sa;sa.sa_flags= SA_NOCLDSTOP| SA_RESTART;sigemptyset(&sa.sa_mask);sa.sa_handler= child_handler;sigaction(SIGCHLD,&sa,NULL);// 信号处理函数实现voidchild_handler(int sig){while(waitpid(-1,NULL, WNOHANG)>0){// 循环回收所有终止的子进程}}

关键配置

  • SA_NOCLDSTOP:不接收停止状态的SIGCHLD
  • WNOHANG:避免处理函数内阻塞
  • 循环处理:防止信号丢失

4.2 多线程环境注意事项

  1. 信号处理线程:指定专用线程处理SIGCHLD

  2. 竞态条件:在fork()后立即设置信号处理

  3. 原子性操作

    sigprocmask(SIG_BLOCK,&mask,NULL);pid_t child=fork();if(child==0){sigprocmask(SIG_UNBLOCK,&mask,NULL);// 子进程逻辑...}sigprocmask(SIG_UNBLOCK,&mask,NULL);

5. 性能优化策略

5.1 批处理模式

#defineMAX_CHILDREN100pid_t children[MAX_CHILDREN];int live_children=0;// 启动批量子进程for(int i=0; i< batch_size; i++){pid_t pid=fork();if(pid==0)exit(worker_task());    children[live_children++]= pid;}// 批量回收while(live_children>0){pid_t pid=waitpid(-1,NULL,0);if(pid==-1)break;for(int i=0; i< live_children; i++){if(children[i]== pid){            children[i]= children[--live_children];break;}}}

5.2 负载敏感策略

// 根据系统负载动态调整等待策略double load=get_load_average();int options=(load>2.0)? WNOHANG:0;do{    pid=waitpid(-1,&status, options);if(pid>0)update_stats(status);}while(pid>0||(pid==-1&& errno== EINTR));

6. 总结

waitpid 系统调用作为 Unix 进程管理的核心组件,其正确使用需注意以下原则:

  1. 精确控制:通过pid参数实现定向回收
  2. 状态完备:完整处理所有可能的终止状态
  3. 资源高效:合理选择阻塞/非阻塞模式
  4. 异常安全:严格检查所有错误返回
  5. 线程安全:多线程环境需特殊处理信号
确定要放弃本次机会?
福利倒计时
::

立减 ¥

普通VIP年卡可用
立即使用
参与评论您还未登录,请先登录后发表或查看评论

博客等级

码龄6年
124
原创
1516
点赞
895
收藏
312
粉丝
关注
私信

热门文章

分类专栏

展开全部收起

上一篇:
多进程服务器
下一篇:
进程间通信

最新评论

大家在看

最新文章

2025

目录

展开全部

收起

目录

展开全部

收起

上一篇:
多进程服务器
下一篇:
进程间通信

目录

评论
被折叠的  条评论为什么被折叠?到【灌水乐园】发言
查看更多评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

[8]ページ先頭

©2009-2025 Movatter.jp