详解 | 求你别用效率低下的I/O了,要不试试这种I/O

本文介绍了操作系统中的IO模型,包括直接IO、缓存IO及其区别,以及阻塞IO、非阻塞IO、同步和异步的概念。详细阐述了BIO、NIO(非阻塞IO)和AIO(异步非阻塞IO)的工作原理,并对比了它们在处理连接请求时的不同。此外,还提到了Linux中的内核空间与用户空间划分,以及IO多路复用技术如select、poll和epoll。文章最后讨论了这些技术在实际应用中的选择,如Netty框架在NIO上的应用。

HI!我是小小,我们又见面了,今天是国庆假期的最后一天,在这最后一天,举国同庆的时刻。。。。我们一块来学习IO,这一次,学习 NIO,BIO,AIO等各种IO

Linux 基础知识回顾

用户空间和内核空间

现在的操作系统都采用虚拟寻址,处理器先产生一个虚拟地址,然后通过地址翻译成为物理地址,再通过总线的传递,最后处理器拿到某个物理地址返回的字节。对于32位操作系统来说,它的寻址空间,为4G,操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限,为了保证用户进程不能直接操作内核,保证内核安全,操作系统把虚拟空间划分为两个部分,一部分为内核空间,一部分为用户空间。对于Linux系统来说,把高直接,1G,给内核使用,称之为内核空间。把低的3G字节,送给进程使用,称之为用户空间。

直接IO和缓存IO

文件系统IO分为直接IO和缓存IO。

缓存IO

读操作

操作系统会检查内核的缓冲区有没有需要的数据,如果已经有缓存了,那么就直接从缓存中返回,否则会从磁盘中读取,然后缓存在操作系统的缓存中。

写操作

把数据从用户空间复制到内核空间的缓存中,并提示用户写操作完成,什么时候写入磁盘,由操作系统随机决定。除非强制调用sync命令。举个栗子,对于write命令来说,数据会先被拷贝进入缓冲区,在拷贝到缓冲区以后才会写入到设备中。

直接IO

直接IO相对于缓存IO少了拷贝到应用进程缓冲区这一步

阻塞和同步

这一小节介绍什么是阻塞,什么是同步

阻塞和非阻塞

阻塞:往往需要等待缓冲区中的数据准备好过后才处理其他事情,否则一直等待在哪。非阻塞: 当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,当数据读取完毕以后,会直接触发,提前监听好的事件的回调函数。若准备好,也会直接返回。

同步异步

同步:应用程序要直接参与IO的读写操作。异步:所有的IO读写交给系统处理,应用程序秩序要等待通知即可,当读的时候,会调用之前设定好的应用程序的回调函数,当写的时候,会调用之前设定好的应用程序的回调函数。

常见的IO模型

常见的IO模型有,阻塞IO,非阻塞IO,I/O复用,信号驱动I/O,异步I/O 比较如下图以读取数据为例子 BIO:如果数据源没有数据会进入阻塞状态,直到获取到数据 NIO,如果数据源没有数据,会直接返回0,不阻塞。AIO:全称异步+非阻塞 详细的见下一节

BIO,NIO,AIO

BIO

同步阻塞IO,服务器实现模式为一个连接一个线程,客户端有连接请求时服务器就需要启动一个线程进行处理,后期可以通过线程池的方式提高性能。适用于连接数目比较小,固定的架构。

NIO

客户端发送的链接请求都会注册到多路复用器上,多路复用器会轮询到连接有IO请求时才启动一个线程进行处理。NIO方式适用于连接数目多,且连接比较短的架构,例如聊天服务器。

IO多路复用模型

IO多路复用,IO就是指我们网络IO,多路指多个TCP连接,复用指复用一个或少量线程,串起来理解就是多个网络IO复用一个或少量的线程处理这些连接。

核心:能处理更多的链接

常用的复用模型,select poll,epoll

select

select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符。

poll

poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。

epoll

epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就绪态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知。

比较

应用和框架

Jetty、Mina、Netty、Dubbo、ZooKeeper 之间的通信,都是基于NIO方式实现。常用的框架有Netty

AIO

一个有效请求一个线程,客户端IO请求都是由OS完成监听和执行的,常用的应用场景有相册服务器。

关于作者

我是小小,一个生于二线,活在一线的程序猿,该程序猿相当相当的佛系,我是小小,我们下期再见。

小明菜市场

推荐阅读

● 明了 | 看了这篇文章,多年不能理解的分布式事物,终于看懂了!

● 推荐 | 作为IDEA的死忠粉,这样设置,效果棒棒哒!

● 异常 | 求你别再写满屏的try-catch了,用全局异常好吗?- 夹私货-行测

● 探讨 | 深入探讨Redis管道

● 必备收藏 | 超详细揭秘 Redis 持久化,建议收藏!

给我个好看再走好吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值