c - 如何使用等待();在一个进程中为了等待它的子进程首先被执行
问题描述
每个printf
命令都代表一个进程。p0
进程应等待p2
进程执行,而p2
应等待至少 2 个子进程(p3,p4,p5
)首先执行:
```
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define _POSIX_SOURCE
int main()
{
int pid1, pid2, pid3, pid4, pid5;
int i;
int status;
pid1=fork();
if (pid1 != 0){
wait(&status);
printf("I'm the parent P0.PID=%d, PPID=%d.\n", getpid(), getppid());}
else{
printf("I'm the child P1 my parent is P0. PID=%d, PPID=%d.\n", getpid(), getppid());
pid2=fork();
if (pid2!=0){
printf("I'm the child P2 and parent to p3,p4,p5.PID=%d, PPID=%d.\n", getpid(), getppid());
pid3=fork();
if (pid3 == 0){
printf("I'm the child P3.PID=%d, PPID=%d.\n", getpid(), getppid());
}
else {
pid4=fork();
if(pid4 == 0)
{
printf("I'm the child P4.PID=%d, PPID=%d.\n", getpid(), getppid());
} else{
pid5 = fork();
if(pid5 == 0)
{
printf("I'm the child P5.PID=%d, PPID=%d.\n", getpid(), getppid());
}
}
}
}
}
/*
if(getppid(&pid1)==getppid(&pid5)){
execl("/bin/ps","ps","-f",(char *)NULL);
}*/
return 0;
}
P0
/ \
P1 P2
/ | \
P3 P4 P5
解决方案
首先,对else
与“ if (pid4==0)
”关联的块使用大括号括起来的块,并确保将“ if (pid5==0)
”块嵌套在里面。这为您提供了更好的内部一致性,但更重要的是,它避免了pid5
在从不设置它的过程中测试值:
else {
pid5=fork();
if (pid5==0){
printf("I'm the child P5.PID=%d, PPID=%d.\n", getpid(), getppid());
}
}
然后,如果您在else
最里面的嵌套中添加一个块if
,它将仅由进程 2 进入。在这样的块中,您可以插入两个调用wait()
来收集两个孩子。
另请注意,wait()
紧随其后的内容if (pid!=0){
似乎放错了位置。当p1是它派生的唯一孩子时,它由p0调用。因此,它将导致p0等待p1,而您声明的意图是等待p2,此时尚未分叉。您表示根本不需要等待p1。等待可能进入与关联的块中。p2
else
if (pid2==0)
然而,还要注意,因为它想专门等待p2,所以p0必须避免在它首先收集p1的可能事件中被愚弄。您可以通过检查wait()
(成功时是收集的孩子的 pid)的返回值来正确处理它,或者您可以改用waitpid()
专门等待进程p2而不是其他的。
推荐阅读
- kotlin - 如何修复分配不是表达式 kotlin,只允许表达式
- javascript - socket.on 在 io.sockets.on('connection,..) 之外不起作用
- javascript - 如何使用 JQuery 停止使用关闭按钮重定向
- python - Python pip install 找不到模块
- java - 在 Mono 上使用 elapsed() 函数?
- c - 如何检查 CLI 定义的 MACRO (-DMACRO=) 是否已定义
- swiftui - 更改选项卡式视图栏颜色 SwiftUI
- java - 如何在骆驼项目中处理蓝图路线中的异常
- php - 在 000webhost.com 上安装 Laravel 项目时出错
- python - 如何减少过期请求?