【发布时间】:2019-04-04 13:34:35
【问题描述】:
我试图了解我的程序为何挂起。父母从a发送输入 它读取到子程序的文件,子程序会将其计算结果发送回它的父程序。但是,我无法通过第二个管道发送回消息。从管道读取时,父级似乎挂起。
从其他帖子中,我读到似乎表明父母应该使用wait 或waitpid 等待孩子完成(在我的情况下,它们都不能解决我的问题)。
我通过添加打印语句注意到父母或孩子都没有完成..有人可以向我解释为什么会发生这种情况吗?
为什么这不起作用?
int main(int argc,char** argv) {
char buffer[1];
int i;
int fd1[2]; int fd2[2];
pipe(fd1); pipe(fd2);
pid_t pid;
// FIRST PROCESS.
// -------------------
pid = fork();
if(pid == 0) {
int cnt;
dup2(fd1[0], STDIN_FILENO);
dup2(fd2[1], STDOUT_FILENO);
for (i = 0; i < 2; i++) {
close(fd1[i]);
close(fd2[i]);
}
while(read(STDIN_FILENO, buffer, sizeof(buffer)) > 0) {
fprintf(stderr, "( %s )", buffer);
cnt = cnt + *buffer - 48;
}
write(STDOUT_FILENO, &cnt, sizeof(cnt));
exit(0);
}
// PARENT.
// ------------------------
int file = open(argv[1], O_RDONLY);
// READ THE FILE.
while(read(file, buffer, 1) > 0) {
if (48 <= *buffer && *buffer <= 57) {
// PIPE TO CHILD.
write(fd1[1], buffer, 1);
}
}
// WAIT FOR CHILD TO FINISH SENDING BACK.
// int status = 0;
// waitpid(pid, &status, 0);
// THIS BLOCK DOESN'T RESOLVE ANYTHING. IT HANGS AT WAIT OR WAITPID.
// **** THIS IS THE PART WHERE IT DOESN'T WORK.
while(read(fd2[0], buffer, 1) > 0) {
fprintf(stderr, "RESULT : %s", buffer);
}
// CLOSING PIPES
for (i = 0; i < 2; i++) {
close(fd1[i]);
close(fd2[i]);
}
close(file);
exit(0);
}
【问题讨论】:
-
如何将 null-terminated 字符串放入只有单个元素的数组中?
-
不要使用magic numbers。如果通过例如
48您的意思是 ASCII 编码字符'0'然后使用该字符。您可能还想了解isdigit函数。 -
最后,不要忘记未初始化的局部变量会有一个 indeterminate 值(可以视为随机或垃圾)。
-
哦,还有一个“最后”的事情:当你在 child 中写
cnt时,它将是你写的 raw binary 值,它可能不包含任何对应的字节完全可打印的字符。 -
EOF 在管道的写端关闭时发送。但是,父 和 子都有一个写端。所以它将保持开放。您必须在不需要它们的进程中显式关闭管道的未使用端(或 CLOEXEC,如果您打算使用 exec)。