这是我第一次使用C,所以到目前为止一直很困难。 我的程序读取file.txt。 在第一行中,我必须创建子项的数量(var:NPROC),在剩下的行中我必须读取子进程的id,两个整数和一个我必须计算的操作的字符: 例如:
.env
我必须使用消息队列(完美地运行)将操作(逐行)发送给孩子,然后孩子应该使用管道发回结果。
这是代码:
(父亲)
NPROC
(id) (n1) (op) (n2)
2
2 3 + 1
1 5 / 2
2 9 * 3
现在我的问题是父亲的阅读似乎没有得到消息。 当我执行程序时,不要退出,它会在父亲的读取中循环(保持不变)。 我试图将读取放在for(因此它至少应该读取最后一条消息),但程序仍然停留在读取中。 如果有人能帮助我,我将非常感激。
答案 0 :(得分:1)
您的代码充满了问题。
switch(currentPid = fork()){
case 0:
在这里你需要关闭管道的读取端:
close(p[0]);
通常在此dup2
之前您有一个execl
。通常,如果您的子进程要加载另一个程序,您希望将其stdout重定向到管道的写入端,如dup2(p[1], 1); close(p[1]);
中所示。
execl("./child", "./child", NULL);
return 0;
case -1:
printf("Error when forking\n");
break;
default:
// in the father
childrenPids[i] = currentPid; // store current child pid
wait(NULL);
此wait
来电是错误的。如果孩子输出的数据多于管道可以同时容纳的数据,那么这里就会出现死锁(孩子将在write
中阻塞,等待父母read
管道的一些数据,然后才能退出;父母将在wait
中阻止,等待孩子退出,然后再从管道中读出来。)
在你给它做任何事情之前等待孩子退出是没有意义的。这不应该是一种类似协处理器的设计,即孩子们应该继续沿着父母运行,根据请求做算术并将结果发回去吗?
printf("\nParentpid: %d, Childpid: %i \n", getpid(), currentPid);
//close(p[1]);
为什么close
被注释掉了?父进程关闭管道的写入端是至关重要的(因为否则从管道的读取端读取将阻塞,因为写入端仍在某处打开(在同一过程中,在这种情况下)。)
if(read(p[0], &val, sizeof(val) == -1){
这行甚至没有编译。缺少)
。
perror("read()\n");
exit(1);
}
你错过了一张EOF支票。 read
在到达数据末尾时将返回0(并且val
未初始化)。
您应该使用管道中的所有可用数据(直到read
返回0
),然后才会使用waitpid(currentPid, NULL, 0);
。