【问题标题】:How to fork() n child processes correctly in C?如何在 C 中正确地 fork() n 个子进程?
【发布时间】:2012-02-05 10:59:01
【问题描述】:

这是我的代码。

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

int main ( int argc, char *argv[] )
{
    int i, pid;

for(i = 0; i < atoi(argv[1]); i++) {
    pid = fork();
    if(pid < 0) {
        printf("Error");
        exit(1);
    } else if (pid == 0) {
        printf("Child (%d): %d\n", i + 1, getpid());
        exit(0); 
    } else  {
        wait(NULL);
    }
}

}

输出是这样的。

Child (1): 5676
Child (2): 4624
Child (3): 4800
Child (4): 5596
Child (5): 5580

但这不是我作业中的预期输出。 应该是这样的。代码有什么问题?有人可以帮我吗?

Child (2): 4625
Child (1): 4624
Child (3): 4626
Child (4): 4627
Child (5): 4628

感谢您的帮助。现在我试试看。

附:对不起,我的英语不好。我希望你能明白我所说的。

【问题讨论】:

    标签: c fork


    【解决方案1】:

    您的代码在我的电脑上完美运行。它可以依赖于操作系统。

    但是,如果您的程序没有参数,您应该检查 argc 是否不等于 1 以避免分段错误。

    【讨论】:

    • 感谢您的建议。
    • 是的,它确实是依赖于操作系统的。我在学校的 Linux 服务器上测试了我的程序。我得到了预期的输出。非常感谢。
    【解决方案2】:

    您得到无序输出的原因是您无法准确预测哪个孩子何时变得活跃。因此,您的第一个孩子的执行可能会延迟到您的第二个孩子是fork()ed 并开始执行。

    您的孩子通常会获得连续的 PID,尽管这取决于操作系统。

    这两个问题不应该是您的计划任务的问题 - 绝对 PID 都不是真正重要的(如前所述,每个操作系统都可以做自己的事情,按顺序或随机分配 PID),也不是孩子的顺序做他们的事情:孩子的每个部分都可以有不同的执行时间,从而导致无序的输出。只要数据被正确传输,这就很重要——如果父级生成序列然后分叉,就是这种情况。在这种情况下,子进程的内存布局与 fork 时父进程的内存布局相同。所以父级可以修改它的“数据传输数组”而不影响已经运行的子级。

    为了减少混淆,您可以删除每行中的 PID 输出。也许它们可以在子进程的相应开始时输出,但在那之后,应该足以说明例如Child 3: straight length 6 &lt;S6,H5,C4,S3,H2,SA&gt; 不重复 PID。

    【讨论】:

    • 谢谢。我已经提供了一些包含在我的作业中的程序的描述。请帮忙。
    • pid分配不仅依赖于OS,子进程的调度也依赖于运行时;没有硬性保证第一个分叉的孩子是第一个计划运行的孩子。
    • @EricTang 更新了解释的答案。
    【解决方案3】:

    系统将空闲的 PID 分配给进程。你可以派生进程 ID 为 4000 并有一个子进程 ID 为 3900。你的作业文件甚至不应该输入数字,因为第一个进程 ID 永远不会相同。

    【讨论】:

    • 谢谢。我已经提供了一些包含在我的作业中的程序的描述。请帮忙。
    【解决方案4】:

    有了预期的输出,你的作业很可能应该首先分叉所有进程,然后调用等待。

    只需跳过循环中的等待调用,然后在下面单独执行一个循环,直到wait 返回-1 并且errno 设置为ECHILD。注意,孩子的输出顺序是随机的,或者至少不是完全按顺序排列的,所以不一定是 2 1 3 4 5。

    这只是一个猜测,如果您想要更具体的答案,您应该提供更多信息。

    【讨论】:

    • 谢谢。我已经提供了一些包含在我的作业中的程序的描述。请帮忙。
    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多