dup2函数参数顺序配图分析

引言: 之前在学习Linux进程间通信时,使用了管道来传递数据。而管道与管道之间对接采用dup2函数进行连接,发现dup2函数的两个参数填充顺序着实有趣,两个管道之间到底是怎么对接成功的呢?学习了一下以配图分析的方式呈现。

一、使用场合

首先介绍这个图: 父进程fork出一个子进程,传递数据给进程,希望子进程去调用一个外部程序来处理并返回数据(比如CGI程序)。
流程: 父进程fork出子进程 ——> 父进程向a[1]写入数据 ——> 父进程等待 ——> 子进程调用外部程序 ——> 外部程序通过STDIN_FILENO拿数据(比如getchar()) ——> 外部程序执行 ——> 外部程序通过STDOUT输出结果(比如printf()) ——> 父进程通过b[0]拿数据
dup2函数参数顺序配图分析_第1张图片

可以发现,图中(1)、(2) dup2函数的参数顺序,都是读写管道对接,到底为什么要这么写呢,这个顺序是固定的吗?需要背吗?其实很多时候我们按照这个顺序写,却没有考虑为什么这么写,那么接下来我们来阐述对接的原理。

二、了解文件描述符

上图中的 STDIN_FILENO、STDOUT_FILENO, a[0]、a[1]、b[0]、b[1] 都是int型的文件描述符。所以首先我们得知道文件描述符是个什么东西,这样才能够解释管道对接的原理

下面这张图来自百度百科,可以看到,文件描述符是是一个进程表项中的文件描述符表中的一项,它由fd标志和文件指针构成。fd标志:在exec后,根据标志为来决定该文件描述符能不能跨exec打开。文件指针:指向一个文件表,该文件表包含了该进程对文件的操作状态、偏移量以及V节点指针。 然而V节点唯一,文件表可以多个(多个进程打开同一个文件的情况)。最后时i索引节点,i索引节点中包含了文件的所有者,文件长度,指向文件实际数据块在磁盘上位置的指针等。
dup2函数参数顺序配图分析_第2张图片

也就是说,我们图一中管道的两端,可以进行替换来看看如下图,管道数据传递实际就是两个节点之间数据的传递,而调用dup2函数时,其步骤为:1.关闭第二个参数的标志; 2.将文件指针指向第一个参数的文件表
请注意:管道是利用内核缓冲区、环形队列实现的,是伪文件。a[0]、a[1]指针是内核缓冲区里的某个地方,由于父子关系,两个进程共用这一块内存。
dup2函数参数顺序配图分析_第3张图片

三、输出重定向

原理讲解差不多了,那么我们将刚才讲解的运用一下,如何将屏幕输出 重定向到一个文件呢?实际就是STDOUT_FILENO与某个文件描述符的dup2函数操作。

dup2(fd1, STDOUT_FILENO);

这样就达到先关闭STDOUT_FILENO的标志,再将其指针指向fd1的文件表,接着printf出来的数据都将被放入fd1所指向的空间,也就达到了重定向的目的。

你可能感兴趣的:(Linux-C)