【问题标题】:Linux process tree using fork()使用 fork() 的 Linux 进程树
【发布时间】:2019-05-03 14:26:05
【问题描述】:

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

我知道代码有点乱,但我是一个初学者,虽然我尝试过,但我无法理解有关进程的许多事情。我正在等待有关代码的一些建议,以及该代码是否正确的意见。提前谢谢你。

【问题讨论】:

    标签: c linux fork


    【解决方案1】:

    您可能希望将任务分解为基本步骤:

    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
    

    【讨论】:

    • 不相关:您在此问题上看不到“编辑标签”选项的原因是因为建议的编辑正在等待处理。当编辑已处于待处理状态时,您无法提交编辑。您可以判断一个编辑处于待处理状态,因为链接更改为“编辑 (1)”。您有权批准、拒绝或改进(批准和编辑)建议的编辑。阅读此评论后,请随意标记。只是想解释一下你所看到的。
    • 感谢您的解释和调查@CodyGray。
    • @MaximEgorushkin 非常感谢您的回答,它对我帮助很大!但是我确实有一个奇怪的问题..当我通过测试仪运行它时,它说进程 2 和 3 的父进程不是 1...不知道为什么会这样
    • @AleM 可能需要您显式创建流程 1,而不是使用原始流程。
    【解决方案2】:

    如果您为每个 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()的结果,因为它也可能失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-15
      • 2016-01-12
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      相关资源
      最近更新 更多