我分割文件,通过pipe()
发送,让孩子找到文件指定部分的总和,通过pipe()
将计算出的总和返回给父级,并让父母计算子总和的总和。
我有一份工作计划。我的问题是它在收到显示正确的最终价值后挂起。
我不确定我在做什么让父母期待更多信息,但我敢打赌它与我的for() loop
包含我的子代码有关。< / p>
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int numchild;
int i, j, len, fpos=0, val, count=0, total=0, alltotal=0;
pid_t pid;
int nums = 1000;
FILE * file;
printf("How many children to use: ");
scanf("%d", &numchild);
printf("\nWill use %d child process(es).\n", numchild);
int fd[2*numchild][2]; //parent+child pipe
// create all pipes
for (i=0; i<2*numchild; i++)
{
pipe(fd[i]);
}
for (i=0; i<numchild; i++)
{
if((pid = fork()) == 0) // child process
{
pid = getpid();
// read from parent
len = read(fd[i][0], &fpos, sizeof(fpos));
if (len > 0)
{
file = fopen("file1.dat", "r");
fseek (file, fpos, SEEK_SET);
count = 0;
total = 0;
printf("Child(%d): Recieved position: %d\n", pid, fpos);
// read from file starting at fpos
// add values read to a total value
while (count < (nums/numchild))
{
fscanf(file, "%i", &val);
total += val;
count++;
}
//write to parent
write(fd[i+numchild][1], &total, sizeof(total));
printf("Child(%d): Sent %d to parent.\n", pid, total);
}
else
{
printf("Child(%d): Error with len\n", pid);
}
_exit;
}
// parent process
pid = getpid();
fpos = ((i*nums*5)/numchild); // 5 is the offset of the file values
// write to child process
printf("Parent(%d): Sending file position to child\n", pid);
write(fd[i][1], &fpos, sizeof(fpos));
// wait for child responce
len = read(fd[i+numchild][0], &total, sizeof(total));
if (len > 0)
{
printf("Parent(%d): Recieved %d from child.\n", pid, total);
alltotal += total;
printf("Parent(%d): Total: %d\n", pid, alltotal);
}
else
{
printf("Parent(%d): Error with len\n", pid);
}
}
}
答案 0 :(得分:1)
我不能问更多问题,但如果这是在Linux或Unix系统上(可能都是posix):
您必须为主程序中的每个子进程执行wait
(man 2 wait
),否则您将创建僵尸进程。
我不知道你在运行什么环境,因此我无法对此进行测试,以确定这是否是导致您无法正常退出的原因。
另外(这更像是一个评论),每个循环通过循环你分娩一个孩子,然后喂它数据,然后得到一个响应,然后打印总数。这真的是你想要做的吗?如果您一次只运行一个孩子,则无需创建一堆管道。
我的猜测是你想要一些实际的并发性。您可以通过创建一个循环来创建所有子节点,然后是另一个循环来为它们提供数据,然后是第三个循环查看结果并对它们求和,然后是第四个循环等待每个子节点终止(到避免僵尸)。
我会考虑使用poll
或select
来阅读回报 - 毕竟,不能保证孩子们能按顺序完成。
答案 1 :(得分:0)
我不会选择这个作为答案,直到其他人告诉我这可能是什么修复它,但我相信我的程序是挂起的,因为main()函数实际上并没有返回任何东西。当我进入时间收集(保存开始时间,结束时间,计算差异,输出)时,它必须在我的for循环之外完成,所以它是我main()方法中的最后一个语句。这似乎已经停止了悬挂。
答案 2 :(得分:0)
在if语句中调用fork()之后,需要调用wait()。这会导致您的父母等待您的孩子退出,然后在孩子退出时继续执行。