Linux的五种IO模型

下面是几种常见I/O模型的对比:

IO

一次文件的读取和输出,正常的文件读取(输出则反之)大致有以下几个步骤

  1. 磁盘 -> 2. 内核 空间-> 3. 用户空间
    所以IO会有用户核和内核的切换
    所有的系统I/O都分为两个阶段:等待就绪和操作。举例来说,读函数,分为等待系统可读和真正的读;同理,写函数分为等待网卡可以写和真正的写。
    需要说明的是等待就绪的阻塞是不使用CPU的,是在“空等”;而真正的读写操作的阻塞是使用CPU的,真正在"干活",而且这个过程非常快,属于memory copy,带宽通常在1GB/s级别以上,可以理解为基本不耗时。
  1. 最简单的IO - 阻塞IO

用户程序调用 内核函数 recvfrom 获取文件数据,但是如果recvfrom 数据没有准备好,用户程序就一直占用线程(阻塞) 等待recvfrom 完成数据复制工作,等数据完成返回继续后面的程序工作,由于阻塞整个流程即同步执行(会有线程上下文切换)

优点:贼鸡儿简单
缺点:1. 等待数据报准备时间消耗,2. 数据拷贝消耗

//doSomeThing()
//代码同步执行,等待recvfrom的返回值
File file = recvfrom();
//processIOContent();

这是一个经典的每连接每线程的模型,之所以使用多线程,主要原因在于socket.accept()、socket.read()、socket.write()三个主要函数都是同步阻塞的,当一个连接在处理I/O的时候,系统是阻塞的,如果是单线程的话必然就挂死在那里;但CPU是被释放出来的,开启多线程,就可以让CPU去处理更多的事情
但是线程的创建和销毁成本很高,在Linux这样的操作系统中,线程本质上就是一个进程。创建和销毁都是重量级的系统函数。
线程本身占用较大内存,像Java的线程栈,一般至少分配512K~1M的空间,如果系统中的线程数过千,恐怕整个JVM的内存都会被吃掉一半。
线程的切换成本是很高的。操作系统发生线程切换的时候,需要保留线程的上下文,然后执行系统调用。如果线程数过高,可能执行线程切换的时间甚至会大于线程执行的时间,这时候带来的表现往往是系统load偏高、CPU sy使用率特别高(超过20%以上),导致系统几乎陷入不可用的状态。
容易造成锯齿状的系统负载。因为系统负载是用活动线程数或CPU核心数,一旦线程数量高但外部网络环境不是很稳定,就很容易造成大量请求的结果同时返回,激活大量阻塞线程从而使系统负载压力过大。

  1. 优化版 IO-非阻塞IO

轮询机制(类似淘宝的二维码登录,前端一直轮询服务端扫码状态,如果成功则跳转显示登录成功),
用户调用recvfrom()函数轮询内核数据准备状态,如果没准备好,则等待下次请求,知道内存数据准备完毕用户调用recvfrom() 函数进行数据赋值,拷贝数据的时候还是阻塞的,只是等待数据报的过程变成了非阻塞
优点:大量减少了数据报准备的消耗
缺点:1. 等待数据报准备时间消耗优化没到极致,2. 数据拷贝消耗在这里插入图片描述

  1. 超级升级版IO - 信号驱动IO

为了避免轮询查询内存数据报准备状态的消耗,产生了信号驱动IO,用户建立sigaction系统调用通知内核,内核收到sigaction 信号后立即返回,并异步准备数据,准备完成后提交 sigio信号通知用户,数据准备完成,
用户收到sigio信号,发起recvfrom系统调用,等待内核数据拷贝到用户控件,内核拷贝完成后返回成功,程序继续处理
优点:避免了阻塞,节省了数据准备的时间
缺点:1.数据拷贝时间消耗 2. 但是一个IO请求还是一个线程,导致数据浪费在这里插入图片描述

  1. IO复用模型

用户发起select 系统调用,查询所有注册到该通道的数据是否有主句报准备好,如果有一个数据报准备好用户就发起recvfrom系统调用,等待内核复制数据报,数据报完成后通知用户数据拷贝完成,

优点:之前一个人管一个通道,现在,一个人管N个通道,有数据的时候就会发起系统调用节省了人力,对应到系统 即减少了线程的开支
缺点:1. 等待数据报还是阻塞,2. 数据报复制 还是阻塞
在这里插入图片描述

  1. 异步IO模型 - AIO (代理模式)

用户发起aio_read()请求后,给内核传递描述符、缓存区指针、缓存区大小等信息。告诉内核完成整个操作和如何通知他,然后就立刻去做其他事情了,内核收到aio_read() 后立即返回请求表示收到,然后自己将数据拷贝到用户指定的缓存区,完成后通知用户
优点: 1. 纯自动贼给力
缺点:难搞哦在这里插入图片描述

五种IO对比

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值