了解下游辩文件描述符,内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文闷和件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
文件描述符的有效范围是 0 到 OPEN_MAX。一般来说,每个进程最多可以打开 64 个文件(0 — 63)。对于 FreeBSD 5.2.1、Mac OS X 10.3 和 Solaris 9 来说,每个进程最多可以打开文件的多少取决于系统内存的大小,神罩缺int 的大小,以及系统管理员设定的限制。Linux 2.4.22 强制规定最多不能超过 1,048,576 。
在Linux *** 作系统中,可以将一切都看作是文件,包括普通文件,目录文件,字符设备文件(如键盘,鼠标...),块设备文件(如硬盘,光驱...),套接字等等,所有一切均抽象成文件,提供了统一的接口,方便应用程序调用
既然在Linux *** 作系统中,你将一切都抽象为了文件,那么对于一个打开的文件,我应用程序怎么对应上呢?
文件描述符应运而生
文件描述符:简称fd,当应用程序请求内核打开/新建一个文件时,内核会返回一个文件描述符用于对应这个打开/新建的文件,其fd本质上就是一个非负整数,读写文件也是需要使用这个文件描述符来指定待读写的文件的
*** 作系统的核心叫内核,是一个独立的软件
*** 作系统为每一个进程维护了一个文件描述符表,该表的索引值都从从0开始的,所以在不同的进程中可以看到相同的文件描述符,这种情况下相同的文件描述符可能指向同一个文件,也可能指向不同的文件,具体情况需要具体分析,下面用一张简图就可以很容易的明白了
通过上图可以看到,当不同进程中出现相同的文件描述符时,可能实际对应的文件并不是同一个,相反不同进程中不同的文件描述符也可可能对应同一个文件
文件描述符是一个重要的系统资源,理论上竖核系统内存多大就应该可以打开多少个文件描述符,但是实际情况是,内核会有系统级限制,以及用户级限制(不让某一个应用程序进程消耗掉所有的文件资源,可以使用ulimit -n 查看)
进程 + 文件描述符ID确认,因为内核为每个进程都有一份其所属的文件描述符表
应用程序进程拿到的文件描述符ID == 进程文件描述符表的索引,通过索引拿到文件指针,指向系统级文件描述符表的文件偏移量,再通过文件偏移量找到inode指针,最终对应到真实的文件
最后说下套接字,套接字也是文件,当server端监听到有连接时,应用程序会请求内核创建Socket,Socket创建好后会返回一个文件描述符给应用程序,当有数据包过来网卡时,内核会通过数据包的源端口,源ip,目的端口等在内核维护的一个ipcb双向链表中找到对应的Socket,并将数老纤和据包赋值到该Socket的缓冲区,应用程序请求读取Socket中的数据时,内核就会将数据拷贝到应用程序的内存空间,从而完成读取Socket数据
这里提一下, *** 作侍盯系统针对不同的传输方式(TCP,UDP)会在内核中各自维护一个Socket双向链表,当数据包到达网卡时,会根据数据包的源端口,源ip,目的端口从对应的链表中找到其对应的Socket,并会将数据拷贝到Socket的缓冲区,等待应用程序读取
最后附上Linux中进程结构图
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)