正确的分叉过程

时间:2018-09-03 00:48:15

标签: c fork

我正尝试将请求发送到服务器,并在每次之前都进行分叉:

int main(void)
{
    // request send
    fork();
// errx() error handling
    return 0;
}

但是,这只会导致1次派生,然后程序崩溃。我一直在网上浏览一些文档,无法弄清楚我在做什么,以及为什么每次尝试查询服务器时它都没有分叉。

2 个答案:

答案 0 :(得分:4)

您的主要问题是执行路径。父进程和子进程都继续运行errx,这显然会终止活动进程,这意味着父进程或子进程中没有迭代。您无需检查fork的结果,它的目的是帮助您确定函数(a)是否起作用,并且(b)当前进程是父进程还是刚派生的子进程。

最好将父进程设置为看门狗,并启动要保护的子进程。下面是一个简单的shell示例,该示例按顺序启动子进程,等待每个子进程终止。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    for (int i=0; i<10; ++i)
    {
        pid_t pid = fork();
        if (pid == 0)
        {
            // handle child process here
            sleep(1);
            return EXIT_SUCCESS;
        }

        if (pid < 0)
        {
            perror("Failed to launch child process");
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("child %d started\n", (int)pid);
            int res = 0;
            pid = wait(&res);
            printf("child %d exited, result = %d\n", (int)pid, WEXITSTATUS(res));
        }

    }
    return EXIT_SUCCESS;
}

示例输出

child 72916 started
child 72916 exited, result = 0
child 72917 started
child 72917 exited, result = 0
child 72919 started
child 72919 exited, result = 0
child 72920 started
child 72920 exited, result = 0
child 72921 started
child 72921 exited, result = 0
child 72923 started
child 72923 exited, result = 0
child 72924 started
child 72924 exited, result = 0
child 72925 started
child 72925 exited, result = 0
child 72926 started
child 72926 exited, result = 0
child 72927 started
child 72927 exited, result = 0

监视批次

对于更复杂的版本,以下命令将以三个批处理的方式启动子进程,然后等待所有三个进程终止,然后再启动下一个批处理。重复三遍,总共九个进程(十个,包括父监视程序)。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    for (int i=0; i<3; ++i)
    {
        // batch launch loop
        int n_children = 3;
        for (int j=0; j<3; ++j)
        {
            pid_t pid = fork();
            if (pid == 0)
            {
                // handle child process here
                sleep(1);
                return EXIT_SUCCESS;
            }
            else if (pid < 0)
            {
                perror("Failed to launch child process");
                --n_children;
            }
            else
            {
                printf("child %d started\n", (int)pid);
            }
        }

        // batch wait loop
        for (int j=0; j<n_children; ++j)
        {
            int res;
            pid_t pid = wait(&res);
            printf("child %d exited, result = %d\n", (int)pid, WEXITSTATUS(res));
        }
    }
    return EXIT_SUCCESS;
}

示例输出

child 73190 started
child 73191 started
child 73192 started
child 73190 exited, result = 0
child 73191 exited, result = 0
child 73192 exited, result = 0
child 73193 started
child 73194 started
child 73195 started
child 73194 exited, result = 0
child 73193 exited, result = 0
child 73195 exited, result = 0
child 73196 started
child 73197 started
child 73198 started
child 73196 exited, result = 0
child 73197 exited, result = 0
child 73198 exited, result = 0

希望您会发现其中的一些帮助。

答案 1 :(得分:3)

您必须记住,主(第一个)进程和子(第二个)进程将执行相同的代码,即errx函数调用。通常使用if / else检查fork的返回值来完成此操作。就像这样:

if (fork() == 0) {
    // you are in the child thread here
}
else {
    // and here you are in the parent
}

,然后在两个线程之间分配逻辑。如果没有,则线程将继续执行相同的代码,直到退出执行。