I/O基本概念

IO相关的内容包含:

1.缓冲区操作

2.内核空间与用户空间

3.虚拟内存

4.分页技术

5.面向文件的IO和流IO

6.多工IO(就绪性选择——IO多路复用)

 

1. 缓冲区

进程执行io操作,归结起来,也就是向操作系统发出请求,让它要么把缓冲区里的数据排干,要么用数据把缓冲区填满。进程使用这一机制处理所有数据的操作。

io操作过程:

用户进程使用read()系统调用,要求其缓冲区被填满,内核即向磁盘控制硬件发出命令,要求其从磁盘读取数据。磁盘控制器把数据直接写入内核空间的内存缓冲区,这一步通过DMA(Direct Memory Access,数字信息号处理器中用于快速数据交换的技术,具有独立于CPU的后台批量数据传输能力)完成,无需主CPU协助。一旦磁盘控制器把缓冲区装满,操作系统内核即把内核空间的临时缓冲区数据拷贝到执行read()调用时进程相应的内存缓冲区

I/O基本概念_第1张图片

用户空间是常规进程所运行的区域,JVM就是常规进程,驻守在用户空间。用户空间是非特权区域,不能直接访问硬件设备。

内核空间能与设备控制器通讯,并控制用户区域进程的运行状态。所有IO都直接或间接通过内核空间。

 

2.虚拟内存

所有现代操作系统都使用虚拟内存。虚拟内存意为使用虚拟地址取代物理地址。虚拟地址的好处:

1)一个以上的虚拟地址可以指向同一个物理地址

2)虚拟地址空间可大于实际可使用的硬件内存

 

设备控制器不能通过DMA直接把磁盘中的数据存储到用户空间,但是利用第一项,可以达到这样的效果。把内核空间地址与用户空间虚拟地址映射到同一个物理地址,这样DMA就可以填充对内核与用户空间进程同时可见的缓冲区。

 

内存空间多重映射:

 

I/O基本概念_第2张图片

 

这样可以省去内核与用户空间的来回拷贝,但是前提条件是,内核与用户缓冲区必须使用相同的页对齐,缓冲区的大小还必须是磁盘控制器块大小(通过为512字节磁盘扇区)的倍数。操作系统把内存地址划分为页,即固定大小的字节组。内存页的大小总是磁盘块大小的倍数。典型的内存页为1024,2048,4096字节。

 

3.内存页面调度

为了支持虚拟内存的第二个特性-寻址空间大于物理内存,必须进行虚拟内存页交换,虚拟内存空间的页面能够保存在外部磁盘存储,这样就为物理内存中的其他虚拟页面腾出了空间。从本质上说,物理内存充当了分页区的高速缓存,而所谓分页区,即从物理内存置换出来,转而存储于磁盘上的内存页面。

I/O基本概念_第3张图片

 

把内存页大小设定为磁盘块大小的倍数,这样内核就可以直接向磁盘控制硬件发布命令,把内存页写入磁盘,在需要时再重新装入,结果是,所有磁盘IO都在页面层完成,对于采用分页技术的现代操作系统而言,这样也是数据在磁盘与物理内存之间往来的唯一方式。

现代CPU包含一个成为内存管理单元(MMU)的子系统,逻辑上位于CPU与物理内存之间,该设备包含虚拟地址向物理地址转换时所需的映射信息,当CPU引用某内存地址时,MMU负责确定该地址所在页(往往通过对地址值进行移位或屏蔽位操作实现),并将虚拟页号转换为物理页号。如果当前不存在与该虚拟页形成有效映射的物理内存页,MMU会向CPU提交一个页错误。

页错误随即产生一个陷阱(类似于系统调用),把控制权移交给内核,附带导致错误的虚拟地 址信息,然后内核采取步骤验证页的有效性。内核会安排页面调入操作,把缺失的页内容读回物理 内存。这往往导致别的页被移出物理内存,好给新来的页让地方。在这种情况下,如果待移出的页已经被碰过了(自创建或上次页面调入以来,内容已发生改变),还必须首先执行页面调出,把页内容拷贝到磁盘上的分页区。如果所要求的地址不是有效的虚拟内存地址(不属于正在执行的进程的任何一个内存段),则该页不能通过验证,段错误随即产生。于是,控制权转交给内核的另一部分,通常导致的结果就是进程被强令关闭。

一旦出错的页通过了验证,MMU 随即更新,建立新的虚拟到物理的映射(如有必要,中断被移出页的映射),用户进程得以继续。造成页错误的用户进程对此不会有丝毫察觉,一切都在不知不觉中进行。 

 

4.文件IO

文件IO属于文件系统范畴,文件系统与磁盘迥然不同。磁盘把数据存在扇区上,通常一个扇区512字节。磁盘属于硬件设备,对何谓文件(文件系统上的概念)一无所知,它只是提供了一系列数据存取接口。在这点上,磁盘扇区与内存页有很多相似之处:都是统一大小,都可作为大的数组被访问。

文件系统是更高层次的抽象,是安排、解释磁盘(或其他随机存取块设备)数据的一种独特方式。我们的所有代码都是与文件系统打交道,而不是直接与磁盘打交道。文件系统定义了文件名,路径,文件,文件属性等抽象概念。

 

文件系统把一连串大小一致的数据块组织到一起。有些块存储元信息,如空闲块、目录、索引 等的映射,有些包含文件数据。单个文件的元信息描述了哪些块包含文件数据、数据在哪里结束、 最后一次更新是什么时候,等等。  

当用户进程请求读取文件数据时,文件系统需要确定数据具体在磁盘什么位置,然后着手把相关磁盘扇区读进内存。老式的操作系统往往直接向磁盘驱动器发布命令,要求其读取所需磁盘扇区。而采用分页技术的现代操作系统则利用请求页面调度取得所需数据。 

操作系统还有个页的概念,其大小或者与基本内存页一致,或者是其倍数。典型的操作系统页从 2,048到8,192字节不等,且始终是基本内存页大小的倍数。

采用分页技术的操作系统执行I/O 的全过程可总结为以下几步:    

1)确定请求的数据分布在文件系统的哪些页(磁盘扇区组)。磁盘上的文件内容和元数据可能跨越多个文件系统页,而且这些页可能也不连续。    

2)在内核空间分配足够数量的内存页,以容纳得到确定的文件系统页。

3)在内存页与磁盘上的文件系统页之间建立映射。    

4)为每一个内存页产生页错误。    

5)虚拟内存系统俘获页错误,安排页面调入,从磁盘上读取页内容,使页有效。    

6)一旦页面调入操作完成,文件系统即对原始数据进行解析,取得所需文件内容或属性信息。

需要注意的是,这些文件系统数据也会同其他内存页一样得到高速缓存。对于随后发生的 I/O请求,文件数据的部分或全部可能仍旧位于物理内存当中,无需再从磁盘读取即可重复使用。 

 

5.内存-文件映射

传统的文件IO是通过用户进程调用read()和write()系统调用来传输数据的。为了在内核空间的文件系统页与用户空间的内存区之间移动数据,一次以上的拷贝操作几乎总是免不了的。但是,还有一种大多数操作系统都支持的特殊类型的IO操作,允许用户进程最大限度地利用面向页的系统IO特性,并完全摒弃缓冲区拷贝——内存映射IO。

I/O基本概念_第4张图片

内存映射 I/O 使用文件系统建立从用户空间直到可用文件系统页的虚拟内存映射。这样做有几

个好处:   

1)用户进程把文件数据当作内存,所以无需发布read( )或write( )系统调用。    

2)当用户进程碰触到映射内存空间,页错误会自动产生,从而将文件数据从磁盘读进内 存。如果用户修改了映射内存空间,相关页会自动标记为脏,随后刷新到磁盘,文件得到更新。    

3)操作系统的虚拟内存子系统会对页进行智能高速缓存,自动根据系统负载进行内存管理。    

4)数据总是按页对齐的,无需执行缓冲区拷贝。    

5)大型文件使用映射,无需耗费大量内存,即可进行数据拷贝。  

虚拟内存和磁盘 I/O 是紧密关联的,从很多方面看来,它们只是同一件事物的两面。在处理大 量数据时,尤其要记得这一点。如果数据缓冲区是按页对齐的,且大小是内建页大小的倍数,那么,对大多数操作系统而言,其处理效率会大幅提升。

 

 

6.文件锁定

        文件锁定机制允许一个进程阻止其他进程存取 某文件,或限制其存取方式。通常的用户是控制共享信息的更新方式,或用于事务隔离。在控制多个实体并行访问共同资源方面,文件锁定是必不可少的。数据库等复杂应用严重信赖于文件锁定。  

    “文件锁定”从字面上看有锁定整个文件的意思(通常的确是那样),但锁定往往可以发生在更 为细微的层面,锁定区域往往可以细致到单个字节。锁定与特定文件相关,开始于文件的某个特定字节地址,包含特定数量的连续字节。这对于协调多个进程互不影响地访问文件不同区域,是至关重要的。  

        文件锁定有两种方式:共享的和独占的。多个共享锁可同时对同一文件区域发生作用;独占锁 则不同,它要求相关区域不能有其他锁定在起作用。 

你可能感兴趣的:(IO)