socket的fd指什么?
fd 是(file descriptor)即文件描述符,这种一般是BSD Socket的用法,用在Unix/Linux系统上。fd全称是file descriptor,是进程独有的文件描述符表的索引。
维基百科上介绍:
file descriptors index into a per-process file descriptor table maintained by the kernel, that in turn indexes into a system-wide table of files opened by all processes, called the file table. This table records the mode with which the file (or other resource) has been opened: for reading, writing, appending, and possibly other modes. It also indexes into a third table called the inode table that describes the actual underlying files
简单的说,就是内核为每个进程维护了一个file descriptor table,file descriptor是file descriptor table的索引,file descriptor table的表项又转而可以索引到系统级的file table,file table又可以索引到系统级的inode table,而这个inode table则真正的描述了底层的文件。系统级的file table还记录了每个文件被打开的方式:读、写、追加…。file descriptor table每个进程都有一个,所以fork的会被拷贝。
Linux 系统中,把一切都看做是文件,当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。一个socket句柄,可以看做是一个文件,在socket上收发数据,相当于对一个文件进行读写,所以一个socket句柄,通常也用表示文件句柄的fd来表示。
Linux中一切皆文件,这句话我们都知道,可见文件的重要性,因此文件的管理在Linux中占据了很大比重,那么操作系统怎么管理文件的呢?
要管理一个东西,那么必须经历两个步骤——描述和组织。
当我们打开一个文件时,系统就会生成一个叫做file的结构体,系统正是用这个file结构体来描述单个文件的;既然已经描述了那么就要组织起来了,系统就会用一个数据结构把所有的文件都组织在一起以方便管理,而我们的进程要能访问这些文件,那么这个数据结构也要与进程关联起来。
在Linux中,进程与文件的模型是这样的:
进程的PCB中保存着一个指向文件组织结构的一个指针,而对于每个打开的文件,在文件组织结构的文件指针数组中都会有一个指针指向它,因此进程只要通过files指针访问到fd_array就可以进入打开的文件了。
所以,当我们用open函数打开一个文件时,其过程为:操作系统生成一个新的file结构体来保存这个文件的信息,并在files_struct的文件数组fd_array中生成一个指向这个file结构体的指针,然后向进程返回这个指针的下标值,而这个下标值正是文件描述符fd,在进程中也正是通过这个fd来访问目的文件。所以,fd就是指向所打开文件的指针在files_struct中的数组 fd_array里面的下标值。
必须注意的是files_struct与file都是在内核中存在的。FILE是C库中的文件描述结构体,这是一个用户层次的结构,里面封装了fd,其结构体定义为:
看到这里,我们能知道,C库中的FILE结构体也是通过fd来管理文件的,当C程序用fiopen打开一个文件时,其实质是通过调用open函数来进行操作的。也就是说FILE结构是对fd的封装,而C库中带f的一系列IO函数(如fopen)是对系统调用(如open)的封装。
1.描述:
2.系统为维护文件描述符,建立了三个表
3.通过这三个表,认识文件描述符
打开
操作有资源的地方就有战争,“文件描述符”也是一种资源,系统中的每个进程都需要有“文件描述符”才能进行改变世界的宏图霸业。世界需要秩序,于是就有了“文件描述符限制”的规定。
如下表:
永久修改用户级限制时有三种设置类型:
soft
指的是当前系统生效的设置值hard
指的是系统中所能设定的最大值-
指的是同时设置了 soft 和 hard 的值命令讲解:
步骤(以nginx为例,*注意权限问题,此示例是在本地环境):
ps aux|grep nginx
如图,找到的主进程id为 30802
1.查看该进程的限制
cat /proc/30802/limits
如图,在 Max open files 那一行,可以看到当前设置中最大文件描述符的数量为100001
2.查看该进程占用了多少个文件描述符
如上图所示:使用了17个文件描述符
实际应用过程中,如果出现“Too many open files” , 可以通过增大进程可用的文件描述符数量来解决,但往往故事不会这样结束,很多时候,并不是因为进程可用的文件描述符过少,而是因为程序bug,打开了大量的文件连接(web连接也会占用文件描述符)而没有释放。程序申请的资源在用完后及时释放,才是解决“Too many open files”的根本之道。
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/56