C 正确的分叉方法

C 正确的分叉方法,c,fork,C,Fork,我正在尝试向服务器发送请求,并在每次请求之前进行分叉: int main(void) { // request send fork(); // errx() error handling return 0; } 但是,这只会导致1个fork,然后程序崩溃。我一直在网上浏览一些文档,无法找出我做错了什么以及为什么每次尝试查询服务器时它都没有分叉。您必须记住,主(第一个)进程和子(第二个)进程都将执行相同的代码,即errx函数调用。这件事通常通过和if/else检查fork

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

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

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

您必须记住,主(第一个)进程和子(第二个)进程都将执行相同的代码,即
errx
函数调用。这件事通常通过和if/else检查fork的返回值来完成。可能是这样的:

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

你把你的逻辑分成两个线程。如果没有,线程将继续执行相同的代码,直到退出执行。

您的主要问题是执行路径。父进程和子进程都继续执行
errx
,这显然会终止活动进程,这意味着父进程或子进程中没有迭代。您不需要检查fork的结果,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;
}

监控批次

对于更复杂的版本,下面的代码将分三批启动子进程,然后等待所有三个进程终止,然后再启动下一批。这将重复三次,总共九个进程(十个,包括父看门狗)


希望你会发现其中的一些有用信息。

我敢问一下这应该是做什么的:
I=I++
?什么是
errx()
?用一个看门狗可能会容易得多。您现在所拥有的将父级和子级发送到
errx
,我假设它会终止您的程序。请参阅对几乎重复的问题的回答question@MartinJames编辑只是为了简化问题,而且似乎不会使答案无效您通常不希望主线程退出并让其他线程运行,即使有可能。让你的主线程在其他线程之后等待,并让不同的子线程相互生成,并在需要时退出。有趣的是,感谢你的洞察力,我将继续努力!没问题,希望你会成功。如果答案看起来不错并且对您有帮助,您也可以将其标记为已接受:-)您忘记处理
fork
的故障,当它返回负值时请记住,如果没有exec,则If{}else{}块之后的代码将由父级和子级执行
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