我一次又一次地编写这个程序,但是我在学习如何使用fork()递归地生成子进程时遇到了问题。我开始编写一些相当复杂的东西,但最终决定从更简单的事情重新开始。
我刚刚开始学习进程,但是我有困难理解它们。该程序旨在派生出一个进程树,但是必须从根派生两个进程,在左侧分别创建3个子进程,在右侧分别创建4个子进程。这些进程必须分别派生自己的3和4个进程。
我遇到的问题是,程序可以fork进程,但是每一侧只有一个进程作为其各自方向上所有子进程的父进程。
如果您能给我任何帮助,那就太好了,请告诉我是否表述不够清楚。
我刚刚开始学习进程,但是我有困难理解它们。该程序旨在派生出一个进程树,但是必须从根派生两个进程,在左侧分别创建3个子进程,在右侧分别创建4个子进程。这些进程必须分别派生自己的3和4个进程。
我遇到的问题是,程序可以fork进程,但是每一侧只有一个进程作为其各自方向上所有子进程的父进程。
如果您能给我任何帮助,那就太好了,请告诉我是否表述不够清楚。
#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个孩子。 - John Zwinckfork()
时,它会收到错误指示或子进程的 pid。在父进程退出之前,需要调用wait()
(或更好的waitpid()
)。如果父进程在所有子进程退出之前退出,则这些子进程将成为“僵尸”进程。僵尸进程除非重新启动计算机,否则无法删除。每个父进程必须为该父进程创建的每个子进程调用wait()
(或waitpid()
)。 - user3629249main()
中,变量status
被传递到three_child()
的两个位置,但它没有被初始化为任何特定的值,并且由于它没有通过地址传递,子函数无法更新它。这需要修复。否则,代码包含未定义的行为。此外,status
在任何地方都没有真正被使用,因此可以消除该参数以及status
的声明。 - user3629249four_child()
,所以发布的代码存在一些“死代码”,并且发布的代码不符合OP问题中的注释。 - user3629249three_child()
在每个由fork()
生成的进程中调用three_child()
,因此生成的进程数量没有限制。 - user3629249