Linux 使用 fork() 的进程树

Linux process tree using fork()

我正在尝试使用 fork() 函数创建以下进程树:

我知道代码有点乱,但我是初学者,尽管我尝试了,但无法理解很多关于流程的事情。我正在等待对代码的一些建议以及该代码是否正确的意见。提前谢谢你。

如果您为每个 pid 使用自己的 pid 变量(例如 p1、p2 ...),它可能不会那么混乱。 如果您评论哪个进程是 运行 分支:

,也许它会有所帮助
pid_t p1, p2, p3, p4, p5, p6, p7;

p1 = getpid(); 
p2 = fork();
if (p2 != 0)    
{
    // P1 runs this branch
    p3 = fork();
    if (p3 == 0)
    {
       // P3 runs this branch
        p4 = fork();
        if (p4 == 0)
        {
            // P4 runs this branch
            p5 = fork();
            if (p5 != 0)
            {
                // P4 runs this branch
                p6 = fork();        
                if (p6 != 0)
                {
                    // P4 runs this branch
                    p7 = fork();        
                }           
            }
        }     
    }
}

您的代码中可能还有其他问题。但是例如这个:

           // create child#1
           fork();

           // create child#2
           fork();

           // create child#3
           fork();

...将生成 7 个孩子的树。

如果您正在创建一个严肃的程序(不仅仅是玩 fork),那么您需要更好地检查 fork() 的结果,因为它也可能会失败。

您可能希望将任务分解为原始步骤:

  1. 编写一个函数来创建一个执行您提供的函数的子进程。
  2. 重复使用函数创建所需的流程树。

示例:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int level = 1;
char const offsets[] = "\t\t\t\t\t\t\t\t";

pid_t create_child_process(int(*child_fn)()) {
    // Flush the output buffers to avoid duplicate output from the child process.
    fflush(stdout);
    fflush(stderr);

    pid_t child_pid = fork();
    switch(child_pid) {
    case 0: // Child process.
        ++level;
        exit(child_fn());
    case -1: // fork() failed.
        abort();
    default: // Parent process.
        printf("%.*s %u spawned %u\n", level, offsets, (unsigned)getpid(), (unsigned)child_pid);
        return child_pid;
    }
}

void wait_for_any_child() {
    int wstatus;
    pid_t child_pid = wait(&wstatus);
    if(child_pid == -1)
        abort();
    printf("%.*s %u terminated\n", level, offsets, (unsigned)child_pid);
}

int p2() { return 0; }
int p5() { return 0; }
int p6() { return 0; }
int p7() { return 0; }

int p4() {
    create_child_process(p5);
    create_child_process(p6);
    create_child_process(p7);
    wait_for_any_child();
    wait_for_any_child();
    wait_for_any_child();
    return 0;
}
int p3() {
    create_child_process(p4);
    wait_for_any_child();
    return 0;
}

int p1() {
    printf("%u started\n", (unsigned)getpid());
    create_child_process(p2);
    create_child_process(p3);
    wait_for_any_child();
    wait_for_any_child();
    printf("%u terminated\n", (unsigned)getpid());
    return 0;
}

int main() {
    return p1();
}

输出:

5962 started
     5962 spawned 5963
     5962 spawned 5964
     5963 terminated
         5964 spawned 5965
             5965 spawned 5966
             5965 spawned 5967
             5965 spawned 5968
             5966 terminated
             5967 terminated
             5968 terminated
         5965 terminated
     5964 terminated
5962 terminated