我想了解管道是如何工作的。此代码片段来自某个网站。
所以我对程序的理解是这样的:
当我们pipe(fd)
这样做时fd[0]=3
,然后fd[0]=4
(假设仅0
,1
&2
到目前为止一直开放)。现在我们分叉父级,如果没有创建子级,则会出现错误并退出。
但是,如果子进程创建成功,文件描述符是否会复制到子进程,我的意思是fd[0]=3
对于fd[1]=4
子进程也是如此?文件句柄fd[0]
是fd[1]
哪些文件(我们没有具体指定)?
让我们假设我们希望孩子从父母那里阅读,那么父母应该关闭fd[0]
,孩子也应该关闭fd[1]
,但为什么呢?如果我们不关闭它们会发生什么?我不明白On a technical note, the EOF will never be returned if the unnecessary ends of the pipe are not explicitly closed.
。
如果父级想要从子级接收数据,则应关闭 fd1,子级应关闭 fd0。如果父级要向子级发送数据,则应关闭 fd0,子级应关闭 fd1。由于描述符在父级和子级之间共享,因此我们应该始终确保关闭我们不关心的管道末端。从技术上讲,如果管道的不必要的末端没有明确关闭,则永远不会返回 EOF。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
int fd[2];
pid_t childpid;
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
}
.
.
}
答案1
Afork
确实是一个叉子。您将获得两个几乎相同的过程。主要区别在于fork()
系统调用的返回值,即被标识为的子进程的 pid家长子进程中为 0(这就是软件如何确定哪个进程被视为家长(父母有责任照顾孩子)哪一个是孩子)。
特别是,内存是重复的,因此fd
数组将包含相同的内容(如果fd[0]
一个进程中为 3,则另一个进程中也将是 3)并且文件描述符也是重复的。孩子中的 fd 3 将指向相同的打开文件描述作为父级中的 fd 3。
因此父级和子级的 fd 3 都将指向管道的一端,fd[1]
父级和子级的 fd 4 ( ) 都将指向管道的另一端。
您希望一个进程使用该管道将数据发送到另一进程。通常,其中一个进程将写入 fd 4,另一个进程将从 fd 3 读取,直到它看到文件结尾。
文件结尾当所有打开到管道另一侧的 fd 都已关闭时就达到了。因此,如果读者不将其 fd 关闭到另一端,它将永远不会看到文件结尾。
类似地,如果读者死了,如果作者没有关闭自己的 fd 到管道的另一端,他将永远不会知道它必须停止写入。