句柄handle的释意:
我们常在代码中看到handle的这个东西,但是就不知道什么意思怎么用。
最近就有这样的困扰,所以搜集了一下资料和查看了额一下工程代码做个简单的总结。
我们通常看到的handle的都是一个非负整数,int类型的,那么就很奇怪为什么可以代码转换为一个对象或者控制块(可以理解为一片空间或者一个结构体)使用。
查看工程代码后发现,handle虽然作为整形数据存在,其实这样看作一个指针。我们在handle的使用过程中会发现,我们首先会分配一快空间为需要的对象,然后用指针指向这片空间。最后强转为int类型,后续在使用过程中,这个数字就是代表这边数据空间的标号,这么说的话有点类似与文件描述符。当使用到这部分的数据时候,就只要再次强转回去就可以使用里面的资源了。
网上看到一个不错的比喻:
我们在饭店吃饭时,我们下单就会得到一个取餐号。我们只要凭号取餐就行,不需要向服务员那边介绍一大堆的信息,我们根据编号就能获取对象或者资源。
inode的理解:
按照上文的说法;我感觉文件系统下的inode就是handle。
我们在linux文件系统下,输入ls -i就会发现每个文件对应一个数字,这个 文件对应的inode号。
每个文件对应一个 struct inode。inode结构体包含很多信息,如文件的权限信息,文件的时间信息等等。使用mknod创建设备节点(我们可以使用函数在驱动中创建,也可以使用mknod命令使用shell脚本创建,创建成功之后会在/dev目录下出现对饮的设备接待点)时,会将inode号和设备号关联起来。若此时内核中已经注册了该设备号的对象(设备驱动),此时会将设备对象的操作方法集合赋值到此处,方便应用态下实现对设备的操作。
文件操作集合i_fop指向了def_chr_fops,这个结构中的open函数指向了chrdev_open。chrdev_open完成的主要工作是:首先根据设备号找到添加在内核中代表字符设备的cdev。找到对应的cedv对象后,用cedv关联的操作方法集和赋值给新建的file结构体中的文件操作集合。并调用操作集合中的open函数,完成真正的打开操作。
一个驱动可能会被多应用打开,那多次打开时是生成多个inode号吗?答案是否定的。inode号是唯一的,那如何表示多次打开一个驱动文件呢?
系统中每个打开的文件在内核空间都有一个对应的file结构体。可以理解为一个设备的驱动对应一个inode号,但是我们系统可能存在多个进程对这个设备进行操作。那怎么区分这个操作呢。我们就需要一个管理这些文件操作的对象,struct file应运而生。每个file对象记录一个进程对于这驱动的操作。
那么在应用层以什么形式体现呢?
答案就是int fd;文件描述符。那么fd是不是可以理解为struct file的handle呢。
上图是我结合流程与我想法总结的应用层open函数的功能实现。
总结:
其中包含了应用调用内核驱动的流程思想(其实就是IO操作的内核实现):
1、linux文件系统下一切皆文件(ls可以发现所有的目录都带一个文件类型);
2、mknod结合inode号(文件handle)与设备驱动(设备号与设备名==文件名-->inode);
3、open的参数(文件名,文件权限),返回值fd(file handle);
4、虚拟文件系统,联系应用和内核的机制;
5、通过inode 的cdev号,找到对应的设备驱动,取出cdev的ops去赋给file,去完成最终操作。