【发布时间】:2017-09-14 10:15:45
【问题描述】:
我一遍又一遍地对此进行编程,并且在学习如何使用 fork() 以递归方式生成子进程时遇到了麻烦。我开始编写一些非常复杂的东西,我决定用更简单的东西重新开始。
我刚开始学习流程,但在理解它们时遇到了困难。 该程序旨在分叉一棵进程树,但是,我必须从根分叉两个将分叉的进程,左侧是 3 个子进程,右侧是 4 个子进程。这些进程必须分别派生出它们自己的进程 3 和 4。
我对此的问题是该程序可以分叉进程,但是每一侧只有一个进程是各自一侧所有孩子的父亲。
你能给我的任何帮助都会很棒,如果我不够清楚,请告诉我。
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
/* Prototypes */
void three_children();
void four_children();
int main()
{
pid_t process;
int status,n;
printf("Number of levels: \n");
scanf("%d", &n);
for (int i = 0; i < n ; i++) {
process = fork();
switch (process) {
case -1:
printf("Error\n");
break;
case 0:
if (i == 0) {
printf("Left\n");
three_children(process, status);
}
if (i == 1) {
printf("Right\n");
three_children(process, status);
}
printf("Hi I'm a child PID: %d, my father is PPID: %d\n", getpid(), getppid());
exit(0);
default:
printf("I'm a father PPID: %d\n", getppid());
break;
}
}
}
void four_children(pid_t process, int status)
{
for (int j = 0; j < 4; j++) {
process = fork();
switch (process) {
case -1:
printf("Error\n");
break;
case 0:
printf("I'm child: %d, and my father is: %d\n(four children)\n", getpid(), getppid());
exit(0);
break;
default:
printf("I'm a father process: %d\n", getpid());
four_children(process, status);
for (int j = 0; j < 3; j++) {
wait(&status);
}
break;
}
}
}
void three_children(pid_t process, int status)
{
for (int k = 0; k < 3; k++) {
process = fork();
switch (process) {
case -1:
printf("Error\n");
break;
case 0:
printf("I'm a child: %d, and my father is: %d\n(three children )\n", getpid(), getppid());
exit(0);
break;
default:
printf("I'm father %d\n", getpid());
three_child(process, status);
for (int j = 0; j < 3; j++) {
wait(&status);
}
break;
}
}
}
【问题讨论】:
-
cuatro_hijos= 4 个孩子,tres_hijos= 3 个孩子。 -
当父级调用
fork()时,它会收到错误指示或子级的pid。在父级退出之前,它需要调用wait()(或者更好的waitpid())。如果父进程在所有子进程退出之前退出,那么这些子进程将成为“僵尸” 僵尸进程无法删除,除非重新启动计算机。每个父母都必须为该父母创建的每个孩子调用wait()(或waitpid()), -
在函数中:
main(),变量status在两个地方被传递给three_child(),但是它没有被初始化为任何特定的值并且因为它没有通过它的'地址,子功能无法更新它。这需要修复。否则代码包含未定义的行为。此外,status并没有真正在任何地方使用,因此可以消除该参数以及status的声明 -
没有人调用该函数:
four_child(),因此发布的代码有一些“死代码”,并且发布的代码不符合 OPs 问题中的注释。 -
函数:
three_child()在fork()生成的每个进程中调用three_child(),所以生成的进程数没有限制