linux总结3:文件系统I/O


    把文件系统挂载到挂载点后,你就能通过挂载点,再去访问它管理的文件了。VFS 提供了一组标准的文件访问接口。这些接口以系统调用的方式,提供给应用程序使用。就拿 cat 命令来说,它首先调用 open() ,打开一个文件;然后调用 read() ,读取文件的内容;最后再调用 write()  ,把文件内容输出到控制台的标准输出中。

    文件读写方式的各种差异,导致 I/O 的分类多种多样。最常见的有,缓冲与非缓冲 I/O、直接与非直接 I/O、阻塞与非阻塞 I/O、同步与异步 I/O 等。 接下来,我们就详细看这四种分类。


    第一种,根据是否利用标准库缓存,可以把文件 I/O 分为缓冲 I/O 与非缓冲 I/O。

        缓冲 I/O:是指利用标准库缓存来加速文件的访问,而标准库内部再通过系统调度访问文件。
        非缓冲 I/O:是指直接通过系统调用来访问文件,不再经过标准库缓存。需要注意,像read()和write()函数,不是直接对磁盘文件进行读取操作,它们都属于系统调用,在用户层没有缓存,所以叫做无缓存IO,但是对于内核来说,还是进行了缓存,只是用户层看不到罢了,内核层还是有缓冲区的。

        无缓存IO操作数据流向路径:数据——内核缓存区——磁盘
        标准IO操作数据流向路径:数据——流缓存区——内核缓存区——磁盘

       带缓冲的I/O的目的是什么呢?
       很简单,带缓冲的I/O的目的就是为了提高效率.减少调用write和read等系统调用函数的次数。             
       带缓冲的I/O库函数(fread, fwrite等,用户空间) <----call--->  不带缓冲的I/O系统调用(read,write等,内核空间)<-------> 读写磁盘
       带缓冲的I/O库函数都是调用相关的不带缓冲的 I/O系统调用来实现的,他们并不直接读写磁盘.

/*********************************************************************************************/

    第二种,根据是否利用操作系统的页缓存,可以把文件 I/O 分为直接 I/O 与非直接 I/O。

        直接 I/O, 是指跳过操作系统的页缓存,直接跟文件系统交互来访问文件。
        非直接 I/O, 正好相反,文件读写时,先要经过系统的页缓存,然后再由内核或额外的系统调用,真正写入磁盘。

        想要实现直接 I/O,需要你在系统调用中,指定 O_DIRECT 标志。如果没有设置过,默认的是非直接 I/O。
不过要注意,直接 I/O、非直接 I/O,本质上还是和文件系统交互。如果是在数据库等场景中,你还会看到,跳过文件系统读写磁盘的情况,也就是我们通常所说的裸 I/O。

 

/*********************************************************************************************/

    第三种,根据应用程序是否阻塞自身运行,可以把文件 I/O 分为阻塞 I/O 和非阻塞 I/O:
        阻塞 I/O:是指应用程序执行 I/O 操作后,如果没有获得响应,就会阻塞当前线程,自然就不能执行其他任务。
        非阻塞 I/O:是指应用程序执行 I/O 操作后,不会阻塞当前的线程,可以继续执行其他的任务,随后再通过轮询或者事件通知的形式,获取调用的结果。

/*********************************************************************************************/

    第四种,根据是否等待响应结果,可以把文件 I/O 分为同步和异步 I/O:
        所谓同步 I/O,是指应用程序执行 I/O 操作后,要一直等到整个 I/O 完成后,才能获得 I/O 响应。
        所谓异步 I/O,是指应用程序执行 I/O 操作后,不用等待完成和完成后的响应,而是继续执行就可以。等到这次 I/O 完成后,响应会用事件通知的方式,告诉应用程序。也就是如果使用aio_read,先将aio_read指令发出去然后内核会做注册,aio_read会立即返回,返回后进程可以去做其他的事,等到可以读的时候,内核会发信号。
        举个例子,在操作文件时,如果你设置了 O_SYNC 或者 O_DSYNC 标志,就代表同步 I/O。如果设置了 O_DSYNC,就要等文件数据写入磁盘后,才能返回;而 O_SYNC,则是在 O_DSYNC 基础上,要求文件元数据也要写入磁盘后,才能返回。
        再比如,在访问管道或者网络套接字时,设置了 O_ASYNC 选项后,相应的 I/O 就是异步 I/O。这样,内核会再通过 SIGIO 或者 SIGPOLL,来通知进程文件是否可读写。

linux AIO的详细使用方式和说明:

https://www.cnblogs.com/sky-heaven/p/10689748.html

异步IO的缺点和局限(网上搜索到的)

        https://www.zhihu.com/question/318398057/answer/639276203

        从这里就能看出异步IO可以在IO模块的执行过程中处理其它任务, 当然很可能是下一件需要IO的任务, 而IO通常来说比较慢, 也就是说, IO任务很可能因为异步IO而导致任务积压, 进而导致内存占用过高而崩溃, 当然做得完善的话可以把任务队列做个限制, 但肯定会增加不少开发上的复杂度. 而同步IO因为一个线程只能同时处理一项IO任务, 所以任务的并发执行量可以很容易控制, 也就不会导致无法预料的内存占用问题, 虽然性能看起来没有异步IO高, 但只要IO本身是瓶颈, 即使是异步IO也无法改进IO的性能, 那么同步IO的性能问题就可以忽略.

 

IO的模型分类如下图:

基本 Linux I/O 模型的简单矩阵

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值