对于dup和fork函数来说,前者是复制一个文件描述符,后者是复制进程,同时相关的文件信息也会被复制。
一、对于Dup 之前已经知道,对于一个进程来说,有一个files_struct来管理所有的相关文件,最终的反应形式其实就是一个文件数组而已:
所谓文件描述符就是数组下标。Dup函数总是从数组第一个元素开始扫描,获取第一个可用的文件描述符(也就是没有关联实际文件的fd),这就是所谓:dup总是使用最小的文件描述符。理解了原理就简单了。 一个Dup操作之后,变成什么情况呢?看下面的图:
例如:dup(fd[y]),从开头找到第一个可以的文件描述符(所谓最小描述符),现在可以发现fd[x]和fd[y]同时指向file!这个千万注意,两个文件描述符指向同一个文件和指向同一个file不一样,指向同一个文件可以是不同的file,但是inode永远唯一,但是此处,fd指向同一个file,那么任意一个操作,另一个一定是同步的! 常见例子:一般来说,初始化的时候,进程都拥有默认的三个文件描述符默认代表,标准输入,标准输出,标准错误。但是这不是硬性规定,你可以自己改呀!例如下面的代码: close(0); dup(fd[x]);/* 这是一个普通文件的文件描述符 */ 这之后,你会发现,0号文件描述符关联上了这个文件(0是最小的文件描述符,所以肯定会被dup选中!)。
2、对于fork函数: 父进程fork之后,子进程和父进程共享父进程打开的文件,那么使用图示表现为:
父子进程有相同的文件fd,并且对应的fd指向相同的file。 常见例子:父子进程使用管道通信时候。在父进程中创建一个pair_pipe,也就是创建一个可以通信的两个文件,一个口用于写,一个用于读。那么fork之后,子进程中复制上面信息,也拥有和父进程相同的pair_pipe,其实指向的就是同一个文件,如下图:
现在关闭父进程的pair_pipe[0],关闭子进程的pair_pipe[1],那么父子进程分别使用pair_pipe[0]和pair_pipe[1]进行通信! 具体的通信图示如下:
|