我正在尝试从父进程中分叉2个进程,但有时我会收到错误(程序没有完成),我不知道为什么:
pid_t pidA, pidB;
pidA = fork();
switch (pidA) {
case -1:
// error handling
return -1;
case 0:
// first child code
break;
default: {
// parent code 1
pidB = fork();
switch(pidB) {
case -1:
// error handling
return -1;
case 0:
// second child code
break;
default:
// parent code 2, I think it's the same like parent code 1. Am I right?
waitpid(-1, NULL, 0);
printf("parent\n");
break;
}
// parent code 3, again same like parent code 1 and 2 ???
// when I use printf("Parent\n"); here it prints Parent 2 times and I don't know why.
}
}
有人可以帮我解决这个问题,找到问题所在。 一些解释会很棒。 谢谢
答案 0 :(得分:1)
考虑流程树:
P
/ \
P C1
/ \
P C2
第一叉:拆分成P和C1
第二叉:分为P和C2
C1
返回并且不打印任何内容。
C2
从切换中断,打印Parent
(注意大写p)并返回。
P打印parent
和Parent
。
这就解释了为什么它会两次打印Parent
。
至于未完成的程序,请检查waitpid()的返回值并尝试相应地调试它。
答案 1 :(得分:0)
你到底想要做什么?
当您第一次进行分叉时,您的第一个子进程基本上什么都不做。
父进程将恢复并再次返回pidB
,然后将继续执行,直到执行waitpid()
函数。
我假设您正在尝试等待新的子代码执行,然后在父级继续打印“父级”之前终止。
你正在等待-1的PID,这可能应该是pidB
。
如果你在开关区外放一个printf()
,孩子将在出路时打印“父”,与产生它的父母一样。如果您希望孩子立即终止,您可能需要一个return语句而不是break。
按原样运行代码,在第二个printf
语句之外使用switch
语句,这是我的输出,使用pidB
显示正在打印的进程:
parent
Parent: pid=25046
Parent: pid=0
结果显示,孩子也是打印的孩子之一。
如果在内部开关案例0中添加一个返回而不是中断,这就是你得到的:
parent
Parent: pid=25095
这是我的建议
// parent code 1
pidB = fork();
switch(pidB) {
case -1:
// error handling
return -1;
case 0:
// second child code
break;
default:
// parent code 2, I think it's the same like parent code 1. Am I right?
waitpid(pidB, NULL, 0); // wait for the child process to finish by using the PID of the child as the argument to waitpid
printf("parent\n");
break;
}
// the child will execute anything here unless you return or otherwise prevent the child process from getting here.