文件描述符(file descriptor)是内核用于高效管理已经打开文件所创建的索引
详细学习内容可看此部分:http://blog.csdn.net/cywosp/article/details/38965239
文件描述符是系统一个比较重要的资源。理论上来说系统有多少内存就可以打开多少的文件描述符
但是实际上会做一定的限制
一般可以打开的文件数量是系统内存的10%,称为系统级限制
也会为单个进程打开文件数做默认值处理,称为用户级限制,default一般为1024
系统为每一个进程维护了一个文件描述符表,该表的值都是从0开始的。
内核一共维护了3个数据结构:
1.进程级的文件描述符表
2.系统级的打开文件描述表
3.文件系统的i-node表
①进程级的描述符表的每一条目记录了单个文件描述符的相关信息
1.控制文件描述符操作的一组标志(ー目前此类的标识仅仅定义了1个,就是close-on-exec)
2.对于打开文件句柄的引用
②内核对于所有打开文件的维护有一个系统级别的描述符表格(open file descriptor),也称为打开文件表(open file table),并将表格中个各个条目称为打开文件句柄(open file handle)。一个打开文件句柄存储了一个打开文 件的全部信息:偏移量,状态,对于该文件i-node对象的引用,文件的属性等等
1.在相同的进程中,不同的文件描述符(1,30)都指向了同一个打开的文件句柄(标号23)
这可能是因为通过调用了dup(),dup2(),fcntl()或者对同一个文件多次调用了open()。
2.进程A的文件描述符2和进程B的文件描述符2都指向了同一个打开的文件句柄(标号73)。
这可能是在调用了fork()之后出现的(即A,B是父子进程关系),或者是当某个进程通过UNIX域套接字将一个 打开的文件描述符传递给另一个进程时,也会发生。再者是不同的进程独自去调用open函数打开了同一个文件, 此时进程内部的描述符正好分配到与其他的进程打开该文件的描述符一样。
3.进程A的描述符0和进程B的描述符3分别指向不同的打开文件句柄,但最终均指向i-node的相同条目(1976),换言之指向了同一文件。
这种情况因为每个进程各自对同一个文件发起了open()调用,同一个进程两次打开同一个文件,也会发生类似 的情况。
注意:
1.两个不同的文件描述符,如果指向同一个文件句柄,那么将共享同一个文件偏移量。因此如果通过其中一个文 件描述符来修改文件偏移量(由调用了read(),write()或lseek()所致),另一个描述符中也可以观察到 变化。无论这两个文件描述符是否属于不同或者相同的进程,都是如此。
2.文件描述符标志(即close-on-exec)为进程和文件描述符所私有。对于这一标志的修改并不会影响到同一个进 程或者不同进程中的其他文件描述符。
3.文件描述符这一概念只存在于Unix/Linux这样的操作系统
4.获取文件描述符最常见的方式是通过本机的open()或者create()(这两个函数被调用成功时会返回一个文件 描述符),或者从父进程继承
5.文件描述符和文件指针的区别:
文件描述符:
每个进程在PCB(Process Control Block)中保存着一份文件描述符表,文件描述符就是这个表的索 引,每个表项都有一个指向已打开文件的指针。
文件指针:
文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构包括一个缓冲区和一个文件描 述符,而文件描述符是文件描述符表的一个索引,所以说文件指针就可以被理解为句柄的句柄。