欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

dup函数分析及应用场景

程序员文章站 2022-05-29 23:51:11
...

dup应用场景分析

Unix系统中支持不同的进程共享的打开文件,dup函数可以复制一个现有的文件描述符,这里的“复制”不是说dup返回完全一样的文件描述符,那是没有意义的。而是返回一个当前可用文件描述符中的最小数值,通过这一新的文件描述符也可以访问该文件。

“共享”的分析

上面提到了“共享”,对于刚接触文件描述符的人来说,可能会有些疑问,为什么要“共享”,将文件描述符作为一个“全局变量”访问不是很方便吗?有这种想法的,往往是因为我们大多数情况下的应用范围都是仅限于1个进程,即便1个进程下有多个线程,对于单进程引用而言,其实是没有“共享”的概念的,因为没有意义,单进程下的所有进程都可以访问同一个文件描述符,当然这个文件描述符必须是全局定义的。所以“共享”仅限于不同进程之间对同一个文件的共享访问。就比如说,在电脑上运行一个QQ,再运行一个微信,同时访问某一个文件,这就是不同进程共享访问那个文件。这里我们再稍微强调一下:
我们所说的文件共享,不是一般意义上的两个进程可以对同一个文件进行读写,而只是共享同一个文件表,也就是共享这个文件的当前偏移量、文件状态标志等信息。

打开的文件在内核中的数据结构

dup函数分析及应用场景
从上图我们可以了解到:
(1)每个进程在进程表中都有一个记录项,记录项包含了一张打开的文件描述符表,该文件描述符表中记录了每个打开文件的文件描述符和指向一个文件表的指针。
(2)内核为每个打开文件维持一个文件表,其中包含文件状态标志、当前文件偏移量和v节点指针。
(3)每个打开的文件都有一个v节点,其中包含了i节点信息,文件类型等。

不使用共享机制,两个进程打开一个相同文件

dup函数分析及应用场景
上图中我们可以看到,两个进程(A和B)都打开同一个文件,那么每个进程都会有自己的文件表,每个进程也都拥有他们关于该文件的自己的文件状态标志,这里要知道,几乎在任何操作系统下,不同进程的地址空间都是完全不同的,所以即便两个进程下的文件描述符是一样的,但是一个进程下的文件状态变化,在另一个进程下是不变的,这就会导致数据不同步或者数据被覆盖,比如:
A进程此时调用read读取3个字节,那么A进程所关联的文件表中的当前文件偏移更新为三,但是因为B进程也拥有它自己的关于该文件的文件表,那么对B进程来说当前文件偏移量仍旧是在文件头处。与A进程无关,他们互不影响。这也是造成进程间数据覆盖的原因。因为A进程写了数据到文件中只影响了自己的文件表而不影响B进程的文件表。那么B进程写数据到文件时就会从头开始写造成数据被覆盖。

为了实现不同进程之间共享文件,使用dup()

为了解决上面提到的不同进程之间文件共享的需求,unix提供了dup()功能,
dup原型如下:

int dup(int fd);

由dup返回的新文件描述符是当前可用文件描述符中最小数值。执行dup函数后的内核结构如下图所示:
dup函数分析及应用场景

进程之间传递文件描述符

如果在B进程中直接调用dup进行赋值某一个文件描述符,dup函数会出错的,原因还是不同进程之间是完全隔离的,直接复制同样的描述符是没有任何意义的,那么如何让两个不同的进程之间进行文件描述符传递呢,这就要用到IPC机制,也就是进程通信机制了,并且调用ioctl函数,关于进程同步,就非常复杂和专业了,这里就不做详解了。

相关标签: Unix/Linux环境编程