目前正在做一些功课,感觉很辛苦。目标是生成 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/