gpt4 book ai didi

c - 如何递归使用 fork()?

转载 作者:太空狗 更新时间:2023-10-29 15:39:59 26 4
gpt4 key购买 nike

我一直在一遍又一遍地编写这个程序,但我在学习如何使用 fork() 递归生成子进程时遇到了麻烦。我开始编写一些非常复杂的东西,然后我决定用更简单的方法重新开始。

我刚开始学习流程,但我很难理解它们。该程序旨在 fork 一棵进程树,但是,我必须从根 fork 两个将 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;
}
}
}

最佳答案

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
typedef struct Node
{
int childrenCount;
struct Node* child[0];
} Node;

Node* makeNode(int children)
{
Node* result = (Node*)malloc(sizeof(Node) + sizeof(Node*) * children);
if (!result) {
exit(1);
}
result->childrenCount = children;
for(int loop = 0;loop < children; ++loop) {
result->child[loop] = NULL;
}
return result;
}

void buildTree(int indent, pid_t parent, Node* node);
void createChild(int indent, pid_t parent, Node* node, int childIndex)
{
pid_t pid = fork();
if (pid == -1) {
exit(1);
}
if (pid == 0) {
buildTree(indent + 1, getpid(), node->child[childIndex]);
srand(parent * 10 + childIndex);
exit(rand());
}
for(int ind = 0; ind < indent; ++ind) {
fprintf(stderr, " ");
}
fprintf(stderr, "Parent: %d Spawned %d\n", parent, pid);
}

void buildTree(int indent, pid_t parent, Node* node)
{
for(int ind = 0; ind < indent; ++ind) {
fprintf(stderr, " ");
}
fprintf(stderr, "Parent %d Has %d Children\n", parent, node->childrenCount);
for(int loop = 0; loop < node->childrenCount; ++loop) {
createChild(indent, parent, node, loop);
}
for(int loop = 0; loop < node->childrenCount; ++loop) {
int status;
int child = wait(&status);
for(int ind = 0; ind < indent; ++ind) {
fprintf(stderr, " ");
}
fprintf(stderr, "Parent: %d Reaped %d with status %d\n", parent, child, status);
}
}

int main()
{
Node* root = makeNode(2);
root->child[0] = makeNode(3);
for(int loopChild = 0;loopChild < 3; ++loopChild) {
root->child[0]->child[loopChild] = makeNode(3);
for(int loopGrandChild = 0;loopGrandChild < 3; ++loopGrandChild) {
root->child[0]->child[loopChild]->child[loopGrandChild] = makeNode(0);
}
}
root->child[1] = makeNode(4);
for(int loopChild = 0;loopChild < 4; ++loopChild) {
root->child[1]->child[loopChild] = makeNode(4);
for(int loopGrandChild = 0;loopGrandChild < 4; ++loopGrandChild) {
root->child[1]->child[loopChild]->child[loopGrandChild] = makeNode(0);
}
}

fprintf(stderr, "Start\n");
buildTree(0, getpid(), root);
fprintf(stderr, "Stop\n");
}

关于c - 如何递归使用 fork()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46216431/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com