进程等待函数(waitpid)

本文详细解析了waitpid函数的参数、返回值及应用场景,对比wait函数,介绍了pid_twaitpid(pid_tpid,int*status,intoptions)的使用方法,包括不同pid值的意义及options参数的控制选项。

waitpid函数原型如下:
pid_t waitpid(pid_t pid , int *status , int options)
与wait函数相比,系统调用二者的作用是完全相同的,但是waitpid多出了两个可由用户控制的参数pid和options。
pid:从参数的名字上可以看出来这是一个进程的ID。但是这里pid的值不同时,会有不同的意义。
1.pid > 0时,只等待进程ID等于pid的子进程,只要该子进程不结束,就会一直等待下去;
2.pid = -1时,等待任何一个子进程的退出,此时作用和wait相同;
3.pid = 0时,等待同一个进程组中的任何子进程;
4.pid < -1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

options:options提供了一些额外的选项来控制waitpid,例如WNOHANGWUNTRACED这两个选项,这是两个常数,可以使用 “|”来链接起来使用,比如:
ret = waitpid(-1,NULL,WNOHANG | WUNTRACED);
如果不想使用这两个选项,可以设置为0,如果选择使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立刻返回,而不像wait那样永远等待。

waitpid的返回值一共有三种情况:
1.当返回正常时,waitpid返回收集到的子进程的进程ID;
2.如果设置了WNOHANG,而调用中waitpid发现自己没有已退出的子进程可收集,则返回0;
3.如果在调用中出现错误,则返回-1,同时errno会被设置成相应的值来提示错误。
在这里插入图片描述
在这里插入图片描述
运行程序:
在这里插入图片描述
父进程在经历过10次失败的尝试后,终于收集到了退出的子进程。
这程序中,让父进程和子进程分别睡眠了10秒钟和1秒钟,代表他们分别做出了10秒钟和1秒钟的工作,父子进程都有工作要做,父进程利用工作间歇查看子进程是否退出,如果退出就收集它。

这里我们把第23行改为waitpid(pc,NULL,0):
在这里插入图片描述
在这里插入图片描述
重新运行后发现:修该后父进程将自己阻塞,直到有子进程退出为止。

### 使用 `waitpid` 函数等待特定子进程的方法及其参数设置 `waitpid` 是一种更灵活的函数,允许父进程针对不同条件下的子进程进行等待操作。它的原型如下: ```c #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *status, int options); ``` #### 参数说明 1. **`pid` 参数** - 若 `pid > 0`:表示仅等待进程 ID 等于该值的子进程终止[^1]。 - 若 `pid == 0`:表示等待与调用进程具有相同进程组的任何子进程终止。 - 若 `pid < -1`:表示等待进程组 ID 等于 `-pid` 的任何子进程终止。 - 若 `pid == -1`:表示等待任意子进程终止(类似于 `wait` 函数的行为)。 2. **`status` 参数** - 它是一个指向整数类型的指针,用来存储子进程退出的状态信息。如果不需要获取状态信息,可以将其设为 `NULL`。 3. **`options` 参数** - 提供额外选项控制行为: - `WNOHANG`:使 `waitpid` 不会挂起调用者,即使没有任何符合条件的子进程已退出也会立即返回[^2]。 - `WUNTRACED`:不仅捕获停止的子进程还报告那些因接收到信号而暂停运行的情况。 - `WCONTINUED`:对于先前被停止但现在又继续执行的子进程提供通知支持(某些系统可能不支持此标志位)。 #### 实现方式 为了实现对某一具体子进程的精确监控,应将第一个参数设定为目标子进程的实际 PID 值 (即满足 `pid > 0`) 。下面给出一段示例代码展示如何利用 `waitpid` 来专门监视某单一子进程: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t child_pid; // 创建新子进程 child_pid = fork(); if(child_pid == 0){ // 子进程逻辑部分 sleep(5); // 模拟耗时任务 exit(78); // 自定义退出码 }else{ int status; // 父进程使用waitpid等待指定PID的孩子结束 pid_t result = waitpid(child_pid, &status, 0); if(result != -1 && WIFEXITED(status)){ printf("Child exited with code %d\n", WEXITSTATUS(status)); } else { perror("Error occurred"); } } return 0; } ``` 在这个例子中,我们创建了一个新的子进程并通过记录其 PID ,随后在父进程中调用了带有确切 PID 数字作为首个实参传入给 `waitpid()` 方法来确保只关注这个特别的后代程序何时完结并取得相应结果数据。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值