IO浅析(Netty 学习一)

IO基本原理

要讲IO,首先我们要了解一下底层read和write系统,应用程序的IO读写都是依赖它们的。read读操作:将内核缓冲区指定的数据复制到用户进程缓冲区;write写操作:将用户内存缓冲区的数据写到内核缓冲区。由此可见,read&write是不操作磁盘的,原因是避免频繁的磁盘读取(磁盘读取会影响操作系统的性能,具体原因不在这里做解释)。
那么以Java的IO为例,一个读操作的流程如下图(同步阻塞式)
读操作示例

应用系统 线程缓冲区 内核缓冲区 磁盘 读操作,阻塞 等待就绪 磁盘读操作,操作系统控制, 与本次读没有直接联系 数据就绪,复制到线程缓存 数据就绪 应用系统 线程缓冲区 内核缓冲区 磁盘

四种常见的IO

了解IO的操作逻辑之后我们聊一聊常见的IO。

同步阻塞IO(Blocking IO)

什么是同步?由用户线程主动发起的IO模式我们称之为同步。阻塞就是发送IO请求之后,用户线程进入阻塞状态,等IO操作就绪后执行后续操作,上面的读取例子就是阻塞式的。

同步非阻塞IO(Non-blocking IO)

与上面的同步阻塞IO相比主要的区别是当用户线程发起IO请求时不会等待内核缓冲区就绪后返回结果,而是马上返回,如果内核缓冲区未就绪,则返回不可用,因此需要用户循环调用确保IO操作顺利执行。虽然去掉了阻塞控制但是又引入了循环调用的开销,整体上来讲并没有提高IO的性能,但是这种IO可以结合其他机制组合使用。这里需要注意JAVA中的NIO并不是这里提到的同步非阻塞IO。

IO多路复用(IO Multiplexing)

这就是JAVA中NIO使用的IO模型,即Reactor反应器设计模式。这种模型中引入一种新的系统调用,查询IO的就绪状态,在Linux系统中是select/epoll系统调用。通过该系统,一个线程,可以监视多个文件描述符,一旦某个就绪就返回给应用系统。操作流程如下:
1.选择器注册,在select/epoll选择器中注册目标socket连接。
2.就绪状态轮询,通过选择器查询注册过的所有socket连接,返回就绪的socket列表,当用户进程调用select查询方法,整个线程阻塞。
3.用户线程获得就绪列表,根据socket连接发起read/write操作。
4.复制完成,解除阻塞,继续执行。
下面是读操作示例
NIO读操作示例

应用系统 线程缓冲区 内核缓冲区 磁盘 select,阻塞,轮询 等待就绪,获取就绪列表 磁盘读操作,操作系统控制, 与本次读没有直接联系 依据就绪列表,复制数据 数据就绪,继续执行 应用系统 线程缓冲区 内核缓冲区 磁盘

选择器中的socket都是同步非阻塞IO,所以IO多路复用也需要轮询,不过用户是无感知的。相对同步非阻塞IO来讲,IO多路复用的优势在于一个线程监控多个文件描述符,这样系统不用创建大量线程以及维护这些线程,从而减少系统开销。由于select/epoll系统调用是阻塞式的,所以并没有彻底解除线程阻塞。

异步IO(Asynchronous IO 简称AIO)

与同步IO不同,异步IO是内核缓存就绪后通知用户线程,以此彻底解除线程阻塞。操作流程如下:
1.用户发起IO调用,用户线程不阻塞,继续操作。
2.内核开始准备数据。
3.数据就绪,内核给用户线程发信号。
4.用户读取用户线程缓冲区数据,完成后续操作。
异步的特点是内核等待数据和复制数据的两个阶段都没有阻塞。用户通过注册IO就绪的回调函数或者监听内核的IO操作完成事件来触发后续的操作。异步IO的缺点是需要操作系统底层支持,现在Linux系统还没有真正的异步IO实现。

到此为止IO的基本原理了解了一个大概,后面开始了解JAVA中的NIO。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值