ImageVerifierCode 换一换
格式:DOCX , 页数:22 ,大小:912.23KB ,
资源ID:15905940      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/15905940.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(一个IO的传奇一生Word格式文档下载.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

一个IO的传奇一生Word格式文档下载.docx

1、如果你想保存你的Word资料至本地硬盘,你就会触发一个文件系统写操作。如果你想将一个文件从本地电脑拷贝到U盘时,你会触发一次文件系统的读写过程。大家知道,为了简化用户对文件的管理,操作系统提供了文件系统对数据资料进行了管理,文件系统是操作系统最为重要的组成部分。一旦你想往文件系统写入数据时,一个新的IO请求就会在用户态诞生,但是,其绝大部分的人生旅程都会在内核空间。对于不同的应用类型,IO请求的属性会大相径庭。除了文件本身应该具备的基本属性(读写权限等)之外,我们还需要考虑文件的访问模式:异步IO还是同步IO?对文件系统的Cache是如何控制的?应用程序和内核程序之间是如何交互的?所以,在创建

2、一个IO时,我们需要考虑很多这样的因素。我们知道,当我们需要进行文件操作的时候,5个API函数是必不可少的。Create,Open,Close,Write和Read函数实现了对文件的所有操作。Create函数用来打开一个文件,如果该文件不存在,那么需要在磁盘上创建该文件。Open函数用于打开一个指定的文件。如果在Open函数中指定O_CREATE标记,那么Open函数同样可以实现Create函数的功能。Close函数用于释放文件句柄。Write和Read函数用于实现文件的读写过程。举个例子,如果用户需要对一个文件进行写操作,那么首先调用Open函数打开想要操作的文件,函数完成之后获取所要操作文

3、件的句柄;然后调用Write函数将数据写入文件;最后采用Close函数释放文件句柄,结束文件写入过程。上述过程大家应该都非常的熟悉,在上述过程中,整个系统到底发生了哪些操作呢?打开文件众所周知,用户态的API函数通过系统调用陷入内核。对于Open函数对应了sys_open函数例程。该函数的主要职责是查找指定文件的inode,然后在内核中生成对应的文件对象。在Linux中,Sys_open函数调用do_sys_open完成具体功能。在do_sys_open中通过do_filp_open函数完成文件名解析、inode对象查找,然后创建file对象,最后执行特定文件对应的file-open函数。Do

4、_filp_open过程中的核心处理函数是link_path_walk。该函数完成了基本的文件路径的解析功能,是名字字符串解析处理实现的核心。该函数的实现基于分级解析处理的思想。例如,当需要解析“/dev/mapper/map0”字符串时,其首先需要判断从何处开始解析,根目录还是当前目录?这个例子是从根目录开始解析的,那么首先获取根目录的dentry对象并开始分析后继字符串。处理过程是以/字符为界按序提取字符串。根据规则,首先我们可以提取“dev”字符串,并且计算该字符串的Hash值,通过该Hash值查找dentry下的inode Hash表,就可以很快的找到/dev/目录下的inode对象。

5、Hash值的计算是比较简单的,把所有字符对应的值累加起来就可以得到一个Hash值。根据规则,依此类推,最后解析得到”/dev/mapper/”目录的inode对象以及文件名字符串“map0”。到这一步为止,link_path_walk函数的使命完成,最后可以通过do_last函数获取或者创建文件inode。如果用户态程序设置了O_CREATE标记,那么系统如果找不到用户指定的inode,do_last会创建一个新的文件inode,并且把这些信息以元数据的形式写入磁盘。当指定文件的inode找到之后,另一件很重要的事情就是初始化file文件对象。初始化文件对象通过_dentry_open函数来实

6、现。文件对象通过inode参数进行初始化,并且把inode的操作方法函数集告诉给file对象。一旦file对象初始化成功之后,调用文件对象的open函数执行进一步的初始化工作。通过上述分析,整个过程看似比较复杂,涉及到dentry,inode以及file对象。其实这个模型还是很简单的。Dentry用来描述文件目录,在磁盘上会采用元数据的方式存储在一个block中,文件目录本身在Linux中也是一个文件。Inode描述一个具体的文件,也通过元数据的方式在磁盘上保存。如果对一个文件系统从根目录开始往下看,整个文件系统是一颗庞大的inode树:在打开一个文件的过程中,文件系统所要做的事情就是找到指定

7、文件的inode,所以在这个过程中会有磁盘元数据读操作。一旦文件所属的inode被找到,那么需要在内存中初始化一个描述被打开文件的对象,这个对象就是file。所以,dentry,inode之类的信息在磁盘上是永久存储的,file对象是在内存中是临时存在的,它会随着文件的创建而生成,随着文件的关闭而消亡。在Linux系统中文件类型是多种多样的,一个USB设备也是一个文件,一个普通的Word文档也是一个文件,一个RAID设备也是一个文件。虽然他们在系统中都是文件,但是,他们的操作方式是截然不同的。USB设备可能需要采用字符设备的方式和设备驱动交互;RAID设备可能需要采用块设备的方式和设备驱动进行

8、交互;普通Word文件需要通过cache机制进行性能优化。所以,虽然都是文件,但是,文件表面下的这些设备是不相同的,需要采用的操作方法显然是截然不同的。作为一个通用的文件系统,如何封装不同的底层设备是需要考虑的问题。在Linux中,为了达到这个目的,推出了VFS概念。在VFS层次对用户接口进行了统一封装,并且实现了通用的文件操作功能。例如打开一个文件和关闭一个文件的操作都是相同的。在VFS下面会有针对不同需求的具体文件系统,例如针对Word文档可以采用EXT3文件系统进行操作,对于磁盘设备可以采用bdev块设备文件系统进行操作。在打开一个文件,对文件对象file进行初始化的时候,会将具体的文件

9、系统操作方法关联到file-f_op和file-f_mapping对象。在后面的读写过程中,我们将会看到针对不同的文件类型,会采用不同的f_op和f_mapping方法。读写文件当一个文件被打开之后,用户态程序就可以得到一个文件对象,即文件句柄。一旦获取文件句柄之后就可以对其进行读写了。用户态的读写函数write对应内核空间的sys_write例程。通过系统调用可以陷入sys_write。Sys_write函数在VFS层做的工作及其有限,其会调用文件对象中指定的操作函数file-f_op-write。对于不同的文件系统,file-write指向的操作函数是不同的。对于EXT3文件系统而言,在文

10、件inode初始化的时候会指定ext3_file_operations操作方法集。该方法集说明了EXT3文件系统的读写操作方法,说明如下:如果文件设备是一个USB设备,并且采用的是字符设备的接口,那么在初始化文件inode的时候会调用init_special_inode初始化这些特殊的设备文件。对于字符设备会采用默认的def_chr_fops方法集,对于块设备会采用def_blk_fops方法集。不同的文件类型会调用各自的方法集。下面章节会对EXT3文件写和块设备文件写进行详细阐述。由于字符设备类型比较简单,在此进行简单说明。Def_chr_fops方法集其实就定义了open方法,其它的方法都

11、没有定义。其实字符设备的操作方法都需要字符设备驱动程序自己定义,每个设备驱动程序都需要定义自己的write、read、open和close方法,这些方法保存在字符设备对象中。当用户调用文件系统接口open函数打开指定字符设备文件时,VFS会通过上述讲述的sys_open函数找到设备文件inode中保存的def_chr_fops方法,并且执行该方法中的open函数(chrdev_open),chrdev_open函数完成的一个重要功能就是将文件对象file中采用的方法替换成驱动程序设定的设备操作方法。完成这个偷梁换柱的代码是:一旦这个过程完成,后继用户程序通过文件系统的write方法都将会调用字

12、符设备驱动程序设定的write方法。即对于字符设备文件而言,在VFS的sys_write函数将直接调用字符设备驱动程序的write方法。所以,对于字符设备驱动程序而言,整个过程很简单,用户态程序可以直接通过系统调用执行字符设备驱动程序的代码。而对于块设备和普通文件,这个过程将会复杂的多。在用户程序发起写请求的时候,通常会考虑如下三个问题:第一个问题是用户态数据如何高效传递给内核?第二个问题是采用同步或者异步的方式执行IO请求。第三个问题是如果执行普通文件操作,需不需要文件Cache?第一个问题是数据拷贝的问题。对于普通文件,如果采用了page cache机制,那么这种拷贝合并在很大程度上是避免

13、不了的。但是对于网卡之类的设备,我们在读写数据的时候,需要避免这样的数据拷贝,否则数据传输效率将会变的很低。我第一次关注这个问题是在做本科毕业设计的时候,那时候我设计了一块PCI数据采集卡。在PCI采集卡上集成了4KB的FIFO,数据采集电路会将数据不断的压入FIFO,当FIFO半满的时候会对PCI主控芯片产生一个中断信号,通知PCI主控制器将FIFO中的2KB数据DMA至主机内存。CPU接收到这个中断信号之后,分配DMA内存,初始化DMA控制器,并且启动DMA操作,将2KB数据传输至内存。并且当DMA完成操作之后,会对CPU产生一个中断。板卡的设备驱动程序在接收到这个中断请求之后,面临一个重

14、要的问题:如何将内核空间DMA过来的数据传输给用户空间?通常有两种方法:一种是直接将内核内存映射给用户程序;另一种是进行数据拷贝的方式。对于PCI数据采集卡而言,一个很重要的特性是实时数据采集,在板卡硬件FIFO很小的情况下,如果主机端的数据传输、处理耗费太多的时间,那么整条IO流水线将无法运转,导致FIFO溢出,数据采集出现漏点的情况。所以,为了避免这样的情况,在这些很严格应用的场合只能采用内存映射的方法,从而实现数据在操作系统层面的零拷贝。在Linux中,我们可以采用memory map的方法将内核空间内存映射给用户程序,从而实现用户程序对内核内存的直接访问。在Windows操作系统中,这种内核空间和用户空间的数据交互方式定义成两种:Map IO和Direct IO。Map IO就是采用内存拷贝的方式,Direct IO就是采用MDL内存映射的方式。在编写WDM Windows设备驱动程序的时候经常会用到这两种数据传输模式。值得注意的是,Windows中的Direct IO和Linux中的Direct IO是完全不同的两个概念。在Linux中Direct IO是指写穿page cache的一种IO方法。第二个问题是异步IO和同步IO的问题。对于普通文件而言,为了提高效率,通常会采用page cache对文件数据在内存进行缓

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1