Netty使用前传-IO模型

文章目录

I/O的工作机制

  1. 用户空间地址:用户程序运行期间使用的空间地址

  2. 内核空间地址:操作系统核心程序运行空间

之所以进行区分是操作系统为了保护系统本身的运行安全,从而将两种类型应用运行空间进行隔离造成,保证了安全但是磁盘IO、网络I/O(磁盘,网课为物理设备只能通过系统调用)过程中需要涉及系统和用户之间数据拷贝。

此处请明晰:是站在线程/进程的层面考虑引出的同步/异步、阻塞/非阻塞

在这里插入图片描述

  1. 同步: 调用者进行一次请求一直等待获取到结果才返回,即调用者主动等待调用结果

  2. 异步: 调用者进行一次请求不用等待结果可以返回继续发起下一个请求或者其他人物,等待有结果后由响应发通知,即调用后被调用者主动通知结果。

    所以同步和异步关注的是调用方和被调用者对于结果的’通知机制’,主动同步等待结果,还是异步通知结果。

  3. 阻塞: 等待待用结果的过程中,该线程被挂起从而阻塞线程

  4. 非阻塞: 等待待用结果的过程中,该线程不被挂起,可以执行别的人任务

阻塞和非阻塞关注的是线程/进程等待结果的过程中的状态,线程是否被挂起。所以基于上述的理解同步有阻塞非阻塞状态,异步不存在阻塞与否

LIUNX的五种网络I/O模型

1. 阻塞IO模型

​ 进程读请求调用内核recv(recvfrom)函数,没有数据内核会等待 则进程阻塞,数组准备完成 则内核将数据复制到用户空间
在这里插入图片描述

2. 非阻塞IO模型

SOCKET 接口设置为非阻塞,进程读请求调用内核recv(recvfrom)函数,没有数据内核返回一个错误,紧接着进程主动轮询内核(数据是否准备好),数据准备完成则内核将数据复制到用户空间。
在这里插入图片描述

3. IO复用模型

​ 进程读请求不在受限于recv(recvfrom)函数阻塞,而是受限于select(poll,epoll)函数,两者不同之处在于select可以以事件监听的形式同时处理多个客户端连接,且只有对应事件真实发生时候才进行处理(缺点:监听的多个连接事件过多的话则轮询时间差会变大,事件处理会有一定的延迟)
在这里插入图片描述

4. 信号驱动IO

进程读请求进行信号驱动 I/O,会注册一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。
在这里插入图片描述

5. 异步IO模型

进程度请求通过aio_read系统调用之后直接返回进行其他处理,等到内核数据准备完毕且复制数据到用户空间完成后通知进程。上述四种IO都是同步调用,只有该IO模型才是真正异步。

在这里插入图片描述

BIO操作的缺点

一个客户端需要使用一个线程来单独处理,对于大并发请求来说性能较差(线程数需要很多,其次线程这种‘’资源切换销毁频繁),第二个例子即使使用线程池使线程得到复用,并使用队列来避免线程过多的情况,虽然比第一个例子性能稍微好的,但是我们发现在read()、write()方法中还是同步阻塞,且阻塞事件取决于I/O线程的处理速度和网络I/O的传输速度。

第一个例子 一个客户端需要使用一个线程来单独处理,对于大并发请求来说性能较差(线程数需要很多,其次线程这种‘’资源切换销毁频繁),第二个例子即使使用线程池使线程得到复用,并使用队列来避免线程过多的情况,虽然比第一个例子性能稍微好的,但是我们发现在read()、write()方法中还是同步阻塞,且阻塞事件取决于I/O线程的处理速度和网络I/O的传输速度。

NIO 的相关概念

  1. Buffer 缓冲区:(减少I/O操作) 针对数据的读和写都是Buffer对象:提供数据结构化访问以及维护读写位置属性的数组,相关属性:capacity(容量),limit(读写结束位置 flip()操作),position(当前读写指针)。 常用的Buffer类有ByteBuffer(字节数组缓冲区),MappedByteBuffer(直接内存映射字节缓冲区 详情参考用户空间和内核空间)。

  2. **channel 通道: ** 进行数据读写的通道,与流stream对应区别在于流式单向的而通道是双向的。功能上可以分成两大类网流IO的SelectableChannel和磁盘IO的FileChannel

  3. Selector 多路复用器: NIO的基础,也是非阻塞得以实现的核心功能组件,本质上其通过轮询注册在其上面的Channel,且只有在某个Channel 发生真正的读、写、连接事件时候去进行处理(也可以处理自己感兴趣的事件),其使用了操作系统多路复用IO模型来使用一个线程监听多个客户端连接。

AIO的相关概念

AIO是一个完全异步的IO模型,每次读写请求过来的时候,线程直接返回,内核数据准备完成并发送到用户空间后回调用其注册的异步回调函数发送最终结果。完全的异步非阻塞

核心API对象

  1. AsynchronousServerSocketChannel: 服务端异步Socket
  2. AsynchronousSocketChannel: 客户端异步Socket
  3. CompletionHandler : 网络读写的回调处理接口,需要实现该接口来处理对应的读写操作,该接口有两个方法
    void completed(V result, A attachment); 连接建立、读操作完成,写操作完成都会触发该方法
    void failed(Throwable exc, A attachment); 在上述操作过程中出现的异常则会触发该回调方法。

有关BIO、NIO、AIO相关实例请参考:nettty学习示例 io-model模块

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值