美文网首页系统原理
理解文件描述符

理解文件描述符

作者: 0爱上1 | 来源:发表于2019-04-19 17:49 被阅读0次

    前言

    何为文件?

    Linux 下,一切皆文件

    在Linux操作系统中,可以将一切都看作是文件,包括普通文件,目录文件,字符设备文件(如键盘,鼠标...),块设备文件(如硬盘,光驱...),套接字等等,所有一切均抽象成文件,提供了统一的接口,方便应用程序调用

    文件描述符

    既然在Linux操作系统中,你将一切都抽象为了文件,那么对于一个打开的文件,我应用程序怎么对应上呢?

    文件描述符应运而生

    文件描述符:简称fd,当应用程序请求内核打开/新建一个文件时,内核会返回一个文件描述符用于对应这个打开/新建的文件,其fd本质上就是一个非负整数,读写文件也是需要使用这个文件描述符来指定待读写的文件的

    内核

    操作系统的核心叫内核,是一个独立的软件

    操作系统为每一个进程维护了一个文件描述符表,该表的索引值都从从0开始的,所以在不同的进程中可以看到相同的文件描述符,这种情况下相同的文件描述符可能指向同一个文件,也可能指向不同的文件,具体情况需要具体分析,下面用一张简图就可以很容易的明白了

    摘自https://www.cnblogs.com/DengGao/p/file_symbol.html

    通过上图可以看到,当不同进程中出现相同的文件描述符时,可能实际对应的文件并不是同一个,相反不同进程中不同的文件描述符也可可能对应同一个文件

    当一个应用程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3。POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号

    文件描述符限制

    文件描述符是一个重要的系统资源,理论上系统内存多大就应该可以打开多少个文件描述符,但是实际情况是,内核会有系统级限制,以及用户级限制(不让某一个应用程序进程消耗掉所有的文件资源,可以使用ulimit -n 查看)

    文件描述符唯一性

    进程 + 文件描述符ID确认,因为内核为每个进程都有一份其所属的文件描述符表

    对应关系

    应用程序进程拿到的文件描述符ID == 进程文件描述符表的索引,通过索引拿到文件指针,指向系统级文件描述符表的文件偏移量,再通过文件偏移量找到inode指针,最终对应到真实的文件

    Socket

    最后说下套接字,套接字也是文件,当server端监听到有连接时,应用程序会请求内核创建Socket,Socket创建好后会返回一个文件描述符给应用程序,当有数据包过来网卡时,内核会通过数据包的源端口,源ip,目的端口等在内核维护的一个ipcb双向链表中找到对应的Socket,并将数据包赋值到该Socket的缓冲区,应用程序请求读取Socket中的数据时,内核就会将数据拷贝到应用程序的内存空间,从而完成读取Socket数据

    这里提一下,操作系统针对不同的传输方式(TCP,UDP)会在内核中各自维护一个Socket双向链表,当数据包到达网卡时,会根据数据包的源端口,源ip,目的端口从对应的链表中找到其对应的Socket,并会将数据拷贝到Socket的缓冲区,等待应用程序读取

    最后附上Linux中进程结构图

    image.png

    相关文章

      网友评论

        本文标题:理解文件描述符

        本文链接:https://www.haomeiwen.com/subject/xlqcgqtx.html