c - 多进程管道

标签 c pipe fork

目前正在做一些功课,感觉很辛苦。目标是生成 100,000 个数字并通过将工作分成 10 个进程(每个进程 10,000 个数字)将它们全部加在一起

我想我已经弄清楚了如何 fork 进程(希望如此),但是使用 Pipe() 来中继每个子进程的小计是行不通的……下面的程序为每个子进程返回 44901,为每个子进程返回 449010运行总计。

我正在努力奋斗,但我觉得这是我应该能够理解的简单事情。

main()
{
    int i;
    pid_t pid;
    int status = 0;
    int fd[2];
    int runningTotal = 0;
    pipe(fd);

    int t;
    int r;

    for (i = 0; i < 10; i++) {
        pid = fork();
        if (pid == 0){
            close(fd[0]);
            t = ChildProcess();
            write(fd[1], &t, sizeof(t));
            exit(0);
        }
        close(fd[1]);
        read(fd[0], &r, sizeof(r));
        runningTotal = runningTotal + r;
        wait(&status);
    }

    printf("%i\n", runningTotal);
}

int ChildProcess() {
    int i;
    int total = 0;
    int r = 0;

    for (i = 0; i < 10000; i++) {
        r = rand() % 10; // 0 to 10
        total = total + r;
    }

    printf("%i\n", total);
    return total;
}

最佳答案

通常,每个子进程都使用一个单独的管道,否则父进程不可能知道它读取的数据来自哪个进程。不过,我认为在这种特殊情况下这不是什么大问题,因为在这里,您实际上并不关心。虽然这仍然让我有点畏缩,但我认为您确实可以只用一根管道来完成这项特定任务。

事实上,我认为您的问题根本不在于管道。它与 rand() 一起使用。所有子进程都计算完全相同的(伪)随机数序列,因为它们都使用相同的(默认)种子。如果要生成不同的数字序列,则需要在每个子进程中调用 srand(),为每个子进程提供不同的种子。 rand() 将生成的数字序列完全由它开始的种子决定。

另外请注意,如果系统的随机数生成器有任何好处,那么各个进程计算的所有总和应该彼此非常接近,并且与您报告的结果非常接近。这是统计学中的中心极限定理的结果,但您可以简单地将其视为较大的结果平均平衡较小的结果。计算余数 mod 10 可能会产生轻微偏差。

关于c - 多进程管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32940575/

相关文章:

angular - 如何创建自定义管道以使用多个复选框进行过滤? Angular 4

c - dbgheap.c 尝试重新分配时出错 *向数组添加空间*

c - C : Unable to identify the logical error 中的图形着色

mongodb - 如何在 golang 中进行 Mongodb 聚合

c - 带有 dup2()-ed 描述符的 FILE * 流 — stdin 不起作用

pointers - 在多个 fork 进程之间共享指针

c - 将值捕获到字符串中时出现问题

c - 我写了一个 mergeSort 代码(来自 clrs 书)但没有得到输出

php - 为什么 PHP pcntl_fork 不能并行运行两个以上的子进程?

c - fork() 作为参数