【发布时间】:2017-08-15 18:45:02
【问题描述】:
这是程序:
int fd[2];
char buf1 [31];
int i;
char buf2;
pipe(fd);
if (fork() == 0) { // child
close(fd[1]); // close writing pipe
for(i = 0; i< 20; i++) {
read(fd[0], buf1, 30);
printf("%s\n", buf1);
}
close(fd[0]);
}
else { // parent
close(fd[0]); // close reading end
buf2 = 'a';
for (i = 0; i < 20; i++) {
write(fd[1], &buf2, sizeof(buf2));
}
close(fd[1]);
}
wait(NULL);
如果里面什么都没有,由于 read 块,我们将首先写入管道。
我的问题是关于 write 功能。 for 循环运行 20 次,每次我都在管道中写入 a。 20次迭代后,写入端的管道将包含aaaaaaaaaaaaaaaaaaaa
在孩子中,我将所有 20 个a's 读入buf1,然后打印结果。
现在管道是空的,因为我们已经写过并阅读了我们写的内容?
由于这里还有一个for循环,所以我们又读了一遍,但是这一次,我认为管道是空的,所以没有什么可读的了。所以我认为阅读20次迭代后的最终输出只是
aaaaaaaaaaaaaaaaaaaa
但实际上是这样的:
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
为什么?读完后管道不是空的吗?
【问题讨论】:
-
读入数据后不清除缓冲区,所以再次打印缓冲区时,第一次读取的数据还在。如果您检查函数调用的返回值,这会更清楚。
-
还请注意,您在读取数据后未能附加空终止符;因此,依赖有一个是不正确的。你走运了。也可能不是,因为如果你使用了
read()的返回值(正确地)来确定终止符应该去哪里,那么你就不会感到困惑了。 -
@JohnBollinger 这取决于;这不是 MCVE,所以我们不知道
buf1的声明在哪里以及如何发生。如果它是静态的而不是在main中发生,或者如果它有一个未包含在此处的初始化,则其余字符为 0 并且是安全的。如果所有这些都在main中,那么是的,这可能是个问题。 -
@DanielH,
buf1的声明在提供的代码中。第二行。 -
@JohnBollinger 但它是在
main中,还是在文件范围内?根据缩进,可能是main,但我们不知道。