1 缓存 I/O (Buffered I/O)介绍

对于传统的操作系统来说,普通的 I/O 操作一般会被内核缓存,这种 I/O 被称作缓存 I/O。缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。

(1) 对于读操作来说,当应用程序尝试读取某块数据的时候,如果这块数据已经存放在了页缓存中,那么这块数据就可以立即返回给应用程序,而不需要经过实际的物理读盘操作。当然,如果数据在应用程序读取之前并未被存放在页缓存中,那么就需要先将数据从磁盘读到页缓存中去。一个典型的读取磁盘中数据的流程图如下所示:

(2) 对于写操作来说,应用程序也会将数据先写到页缓存中去,数据是否被立即写到磁盘上去取决于应用程序所采用的写操作机制:如果用户采用的是同步写机制( synchronous writes ), 那么数据会立即被写回到磁盘上,应用程序会一直等到数据被写完为止;如果用户采用的是延迟写机制( deferred writes ),那么应用程序就完全不需要等到数据全部被写回到磁盘,数据只要被写到页缓存中去就可以了。在延迟写机制的情况下,操作系统会定期地将放在页缓存中的数据刷到磁盘上。与异步写机制( asynchronous writes )不同的是,延迟写机制在数据完全写到磁盘上的时候不会通知应用程序,而异步写机制在数据完全写到磁盘上的时候是会返回给应用程序的。所以延迟写机制本身是存在数据丢失的风险的,而异步写机制则不会有这方面的担心。

缓存 I/O 优点:

缓存 I/O 使用了操作系统内核缓冲区,在一定程度上分离了应用程序空间和实际的物理设备。

缓存 I/O 可以减少读盘的次数,从而提高性能。

缓存I/O缺点:

在缓存 I/O 机制中,DMA 方式可以将数据直接从磁盘读到页缓存中,或者将数据从页缓存直接写回到磁盘上,而不能直接在应用程序地址空间和磁盘之间进行数据传输,这样的话,数据在传输过程中需要在应用程序地址空间和页缓存之间进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。对于某些特殊的应用程序来说,避开操作系统内核缓冲区而直接在应用程序地址空间和磁盘之间传输数据会比使用操作系统内核缓冲区获取更好的性能。

2 Linux环境下的network I/O

网络IO的本质就是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。文章开始的时候也提到了,对于一次IO访问(以read为例),数据会先被拷贝到操作系统内核的缓冲区,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间中。

所以说,当一个read操作发生时,它会经历两个阶段:

第一个阶段:等待数据准备。

第二个阶段:将数据从内核拷贝到进程中

对于socket流而言:

第一步:通常涉及等待网络上的数据分组到达,然后复制到内核的某个缓冲区。

第二步:把数据从内核缓冲区复制到应用进程缓冲区。

Linux环境下的五种IO Modle: blocking IO, nonblocking IO, IO multiplexing, signal driven IO, asynchronous IO. 其中前四种比较常见。

(1) blocking IO

在阻塞IO模型中,从调用系统函数获取数据开始到得到数据,当前的进程或者线程始终是处于阻塞状态的,也就是什么都不干,直到等完数据准备好和将数据搬迁到用户空间为止:

1) 用户首先发出系统调用函数希望获取数据;

2) 系统调用会进入内核检查是否有数据准备完毕,如果没有就一直等待;

3) 当数据准备完毕的时候会将数据拷贝到用户空间;

4) 拷贝完毕返回一个获取数据成功的返回值来告诉用户可以进行数据的处理了;在此期间,用户进程或者线程一直是处于阻塞状态的,无论是等待数据还是进行数据的拷贝;

(2) nonblocking IO

和阻塞式的IO模型不同,当发出了系统调用的时候,如果这时候数据还没有准备好,进程或线程并不会进入阻塞模式一直等待,而是会反复轮询“数据好没…数据好没…数据好没…”,这是比较耗CPU资源的,而当数据准备好之后会和阻塞IO模型一样进行数据的拷贝:

1) 首先用户发出系统调用,去向内核申请获取想要的数据;

2) 内核检查发现数据还没准备好,就会返回一个错误值;

3) 用户接收到错误值并不甘心,就会反复反复询问内核是否有数据准备好;

4) 内核一直检查直到有数据准备完毕,进行数据的搬迁,这时用户会进入阻塞等待状态等待数据拷贝完毕;

5) 数据提取到用户空间之后会返回一个成功状态通知用户数据完毕,这时用户就可以进行数据的处理了;

(3) IO multiplexing

既然是复用,说明一次性可以管理或处理多个IO,主要是靠select函数或者poll(epoll)函数来完成;这些函数同样会阻塞进程,但是和阻塞式IO不同的是IO复用模型可以一次性阻塞多个IO操作。同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。

1) 用户首先调用select或者poll函数对多个IO接口操作进行检测,同时会使进程或者线程阻塞;

2) 当有至少一个IO接口响应的时候,系统就会通知内核调用相应的函数来获取数据;

3) 这时内核将数据拷贝迁移至内核空间,进程或者线程仍然处于阻塞状态;

4) 数据就绪,返回一个成功值告诉用户可以处理数据了;

(4) signal driven IO

用户首先注册一个处理IO信号的信号处理函数,当数据还没准备好的时候进程或者线程并不阻塞,当数据准备好的时候用户进程或者线程会收到一个信号SIGIO,这时候就会调用信号处理函数,在信号处理函数中调用IO函数操作数据,完成之后通知用户:

1) 用户程序中事先注册好一个对于SIGIO的信号处理函数;

2) 当数据准备完毕的时候会向用户进程或者线程发送一个SIGIO信号,这时信号就会被捕捉;

3) 捕捉信号之后就会执行用户自定义的一个信号处理函数,并且在函数中调用系统函数去获取数据;

4) 获取数据同样会将数据进行拷贝到用户空间,这时进程或者线程仍然会被阻塞;

5) 当数据准备完毕同样会通知用户,之后就可以进行数据的处理了;

(5) asynchronous IO

对于异步的IO模型来说,数据的等待和搬迁都不由当前的进程或者线程来处理,调用相应系统函数之后就会直接返回继续执行,因此当前用户程并不会被阻塞,当数据已经在用户空间准备就绪之后会以状态、通知或者回调来告诉用户可以进行数据的处理了:

1) 用户程序调用aio_read函数,告诉内核描述字、缓冲区指针、缓冲区大小、文件偏移以及通知的方式,之后便立即返回;

2) 这时内核相应的数据操作组件会进行数据的等待和搬迁,期间用户程序并不受影响继续执行;

3) 当数据都已经在用户空间准备就绪之后就会通过在函数中预留的通知方式来通知用户程序处理数据;

总结:

从上面的分析中不难发现,在对于数据的获取过程中都是进行了两个主要的部分:数据的等待和数据的搬迁;除此相同点之外,下面就总结一下各种IO模型的区别:

从上面的比较可以发现:前四种IO模型也就是阻塞IO、非阻塞IO、IO复用和信号驱动IO模型都是同步的,只有最后一种是异步的异步IO模型;默认情况下所创建出来的socket都是以阻塞的形式,比如网络通信中的recvfrom和sendto,或者read和write等函数都是以阻塞的方式来实现的。

linux network io,Linux network I/O相关推荐

  1. 漫谈linux文件io,Linux文件IO与通用块层的请求合并

    本文参考https://mp.weixin.qq.com/s/Imt4BW-zoHPpcOpcKZs_AQ, 公众号"Linux阅码场" 请求合并就是将进程内或者进程间产生的在物理 ...

  2. linux vmstat io,linux磁盤IO查看iostat,vmstat

    linux磁盤IO查看(iostat) ############## # #    操作 # ############## # iostat -x 1 10 Linux 2.6.18-92.el5xe ...

  3. linux vmstat io,Linux性能监控2(vmstat)

    vmstat : virtual memory statistics(虚拟内存统计),vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使 ...

  4. 如何查看linux网络io,linux 查看CPU内存 网络 流量 磁盘 IO

    使用vmstat命令来察看系统资源情况 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? Q: 在命令行方式下,如何查看CPU.内存的使用情况,网络流量和磁盘I/O? A: 在命 ...

  5. linux 导出io,Linux基础知识之IO重定向

    该博文以CentOS6.8_x86_64系统为基础,Xshell 5远程连接CentOS系统,以root身份登录系统. 什么是I/O重定向? 所谓I/O重定向简单来说就是一个过程,这个过程捕捉一个文件 ...

  6. MySQL 调优基础:Linux内存管理 Linux文件系统 Linux 磁盘IO Linux网络

    http://www.cnblogs.com/digdeep/category/739915.html

  7. linux系统优化 io,Linux硬件IO的优化简介

    首先简单介绍下有哪些硬件设备如下(由于硬件种类厂家等各种因素我就不在此多做介绍有兴趣的可以自行学习): 1.CPU:中央处理器,是计算机运算控制的核心部件之一,相当于人的大脑.如下图 2.RAM:内存 ...

  8. Linux 基础—— IO 全面介绍

    Linux - 基础 IO Linux - 基础 IO 文件 IO 相关操作 stdin & stdout & stderr 系统文件 I/O 文件的宏观理解: 狭义理解: 1.文件在 ...

  9. Linux 性能监控 : CPU 、Memory 、 IO 、Network

    一.CPU 1.良好状态指标 CPU利用率:User Time <= 70%,System Time <= 35%,User Time + System Time <= 70% 上下 ...

最新文章

  1. nuxt渲染html文件,Nuxt页面级缓存
  2. 转 AIX7.2+11.2.0.4RAC实施
  3. IOS判断用户的网络类型(2/3/4G、wifi)
  4. 【转】 不适用Sqrt函数开方,精度小于指定精度
  5. Redis操作Set的相关API
  6. linux2.6内核compat_ioctl函数
  7. Deep Learning of Binary Hash Codes for Fast Image Retrieval(2015)
  8. [转]网站嵌入天气预报
  9. AndEngine 动态更新Text文本内容时报ArrayIndexOutOfBoundsException错误的解决
  10. 在matlab中进行遥感影像地理坐标的相互转换
  11. vscode 添加库头文件_VSCode配置C/C++并添加非工作区头文件的方法
  12. 使用 C# 开发智能手机软件:推箱子(十)
  13. 【外刊阅读】1. There is no “gay gene“
  14. java微信小程序支付-回调(Jsapi-APIv3)
  15. idea安装及学生邮箱获取一年使用权
  16. 2021年数维杯数学建模分析和思路——B题
  17. table固定列html5,css+js简单实现table固定首行首列
  18. WAF学习之一——Nginx与反向代理
  19. Python语言零基础入门教程(一)
  20. PDF批量加水印及加密解密

热门文章

  1. 携程是如何借助“预测式外呼”提高呼叫效率的
  2. BZOJ 2836 树链剖分+线段树
  3. iOS 应用取消时间栏
  4. 【转】python常用工具代码
  5. 宽带ADSL安装过程的18个问答
  6. Fluent NHibernate实战(原创)
  7. 拿什么拯救你,程序新丁?
  8. 指向老域名的反链丢失问题
  9. [源码]C# to SQL 的翻译器.net 1.1版
  10. nginx linux下载文件,linux – 从nginx缓慢下载大型静态文件