【发布时间】:2020-11-16 23:54:24
【问题描述】:
我对如何在 C 中正确使用接近关闭的管道感到困惑。我对 C 相当陌生,所以如果这太简单了,我深表歉意,但我在其他地方找不到任何解释。
#include <stdio.h>
int main()
{
int fd[2];
pipe(fd);
if(fork() == 0) {
close(0);
dup(fd[0]);
close(fd[0]);
close(fd[1]);
} else {
close(fd[0]);
write(fd[1], "hi", 2);
close(fd[1]);
}
wait((int *) 0);
exit(0);
}
我的第一个问题是:在上面的代码中,子进程会关闭fd的写端。如果我们先到达close(fd[1]),然后父进程到达write(fd[1], "hi", 2),那fd[1]不是已经关闭了吗?
int main()
{
char *receive;
int[] fd;
pipe(fd);
if(fork() == 0) {
while(read(fd[0], receive, 2) != 0){
printf("got u!\n");
}
} else {
for(int i = 0; i < 2; i++){
write(fd[1], 'hi', 2);
}
close(fd[1]);
}
wait((int *) 0);
exit(0);
}
第二个问题是:在上面的代码中,我们有没有可能在子进程接收完所有内容之前,到达父进程中的close(fd[1])?如果是,那么父母与孩子之间的正确沟通方式是什么。我的理解是,如果我们不关闭父级中的fd[1],那么读取会一直被阻塞,程序也不会退出。
【问题讨论】:
-
一个文件直到所有引用它的进程都关闭它们的描述符后才真正关闭。所以关闭发生的顺序无关紧要,因为其他进程保持打开状态。
-
子进程可以关闭其文件描述符,但这不会将父进程的文件描述符与内核中的底层打开文件描述分离。 反之亦然。
-
您的子进程不会从管道中读取,但可以。您的父进程确实会写入子进程。在所有正常情况下,关闭都是正确的。在异常情况下,使用
dup2()可能更安全,但我们说的是非常异常的情况。 -
在您的第二个程序中,您有一个未初始化的指针。读进去会让人不开心。
标签: c pipe system-calls