多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

wait 与 waitpid 对比

wait 与 waitpid 对比 底层都是调用 Linux 的waitpid()系统调用wait只是一个简化包装。1. 函数原型$ret wait(); # 无参数 $ret waitpid($target_pid, $flags); # 两个参数2. 核心功能wait()等待任意一个已经退出的子进程谁先僵尸就回收谁。返回被回收子进程的 PID没有子进程时返回 -1行为阻塞直到抓到任意子进程退出。等价于waitpid(-1, 0)✅ 优点写法简单不用写 PID ❌ 缺点不锁定目标。如果存在多个子进程它会抢先回收最先死掉的那一个不一定是你想要的。waitpid($pid, $flags)定向等待指定的子进程由第一个参数$pid控制目标。$pid 0只等待这个特定 PID我们监控脚本的用法$pid -1等价于wait()等待任意子进程$pid 0等待同进程组内任意子进程$pid 0等待该绝对值对应的进程组内任意子进程第二个参数$flags标志位0阻塞模式卡住直到目标子进程退出WNOHANG非阻塞立刻返回不会卡住需要use POSIX✅ 优点意图明确锁定目标 PID支持非阻塞模式。 ❌ 缺点要写 PID代码长一点点。3. 返回值统一规则两者一样返回 0成功数值就是刚刚退出的子进程 PID返回 0仅 WNOHANG 非阻塞模式目标子进程还活着返回 -1出错没有子进程 / PID 不存在注意阻塞模式flags0下 waitpid 永远不会返回 04. 退出状态 $?wait /waitpid 执行成功后都会填充全局变量$?里面是打包的退出状态字。 解析方式完全相同# 手动位运算 my $exit_code $? 8; my $signal_num $? 0xff; # 或者用POSIX宏可读性更好 use POSIX qw(WEXITSTATUS WTERMSIG); my $exit_code WEXITSTATUS($?); my $signal_num WTERMSIG($?);5. 场景选择重点适配你的脚本场景 A父进程只会 fork 出唯一 1 个子进程wait()和waitpid($kid,0)都可以正常工作。# 写法简单 wait; # 意图明确推荐严谨脚本 waitpid($kid,0);虽然 wait 能用但维护角度推荐 waitpid。未来如果新增别的子进程代码不会突然出现诡异 bug。场景 B父进程存在多个子进程❌ 不能用wait()它会抢收任意子进程逻辑错乱。 ✅ 必须用waitpid(特定PID, 0)定向等待。场景 C循环里一边干活一边探测子进程是否结束非阻塞❌ wait () 做不到wait 会卡住不动。 ✅ waitpid WNOHANG非阻塞探测。6. 极简对照表项目wait()waitpid($pid, $flags)等待对象任意子进程由 $pid 指定可以锁定单个 PID是否阻塞永远阻塞flags0 阻塞WNOHANG 非阻塞参数无两个参数多子进程场景危险乱回收安全可以锁定目标底层waitpid (-1,0) 的封装原生系统调用7. 一句话总结wait()等待随便哪个子进程适合一次性、只有单个子进程的简单脚本扩展性差。waitpid($pid,0)只等你指定的那一个子进程意图清晰适合运维 / 监控这类严谨脚本优先选这个。
返回列表