提问:句柄是什么?和文件描述符是什么关系?
网友回答:
句柄
Windows下的概念。句柄是Windows下各种对象的标识符,比如文件、资源、菜单、光标等等。文件句柄和文件描述符类似,它也是一个非负整数,也用于定位文件数据在内存中的位置。
由于Linux下所有的东西都被看成文件,所以Linux下的文件描述符其实就相当于Windows下的句柄。文件句柄只是Windows下众多句柄中的一种类型而已
文件描述符
本质上是一个索引号(非负整数),系统用户层可以根据它找到系统内核层的文件数据。这是一个POSIX标准下的概念,常见于Linux系统。内核(kernel)利用文件描述符来访问文件。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要文件描述符来指定待读写的文件。
两者比较
一个描述符上可以监控很多的事件,如果监控的是read,然而write事件到来的时候也会将该描述符唤醒
lsof在用户空间,主要还是从文件描述符的角度来看文件句柄
简单来说,每个进程都有一个打开的文件表(fdtable)。表中的每一项是struct file类型,包含了打开文件的一些属性比如偏移量,读写访问模式等,这是真正意义上的文件句柄。
而这其中,文件描述符可以理解为一个fdtable的下标,文件句柄是下标指向的数据(这块可以类比于数据下标和数据中的元素)
每个文件描述符都与一个文件所对应的,不同的文件描述符也可能会指向同一个文件,相同的文件描述符也可能会指向不同的文件。这个主要是因为同一个文件可以被不同的进程打开,也可以被同一个进程的多次打开。系统为每一个进程维护了一个文件描述符表,所以在不同的进程中会看到相同的fd。那么要理解具体的内部结构,需要理解下面这三个数据结构:
进程级的文件描述符表
系统级的打开文件描述符表
文件系统i-node表
进程级别的文件描述符表每一条都只是记录了单个文件描述符的信息,主要包含下面几个:
控制文件描述符操作的一组标志
对打开文件句柄的引用
内核对所有打开的文件都有一个系统级的文件描述符表,各条目称为打开文件句柄(open file handle)一个打开文件句柄存储了一个与一个打开文件相关的所有信息
当前文件偏移量(调用read()和write()时更新,或使用lseek()直接修改)
打开文件时的标识(open()的flags参数)
文件访问模式(读写)
与信号驱动相关的设置
对该文件i-node对象的引用
文件类型(常规文件、socket等)和访问权限
一个指针,指向该文件所持有的锁列表
文件的各种属性,时间戳啥的,巴拉巴拉
文件描述符、打开的文件句柄、i-node关系
在进程A中,文件描述符1和30都指向了系统文件描述符表中的21句柄,这可能是通过dup() dup2() fcnt()或者对同一个文件调用了多次open()导致的
进程A的文件描述符2和进程B的文件描述符2都指向了系统文件描述符的30句柄,这可能是fork()的作用,出现了父子进程
进程A的文件描述符0和进程B的文件描述符3分别指向了不同的句柄,但是最后这两个句柄都指向了i-node表中的66,也就是指向了同一个文件。这是因为进程A和B各自同一个文件发起了open()的操作