五分钟掌握同步异步I/O同步阻塞同步非阻塞异步阻塞异步非阻塞

网络通讯原理

在讲I\O的时候,先简单讲下网络通讯原理。
网络通讯四要素:本机的IP地址、子网掩码、网关的IP地址和DNS的IP地址。
四要素有两种方式:一是静态获取,即手动配置;二是动态获取,即通过DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)获取

网络通讯的过程

  • 浏览器解析网址(IP地址+协议+端口号),通过访问DNS域名系统服务器(基于UDP)获得IP地址
  • 生成HTTP消息并转交给Socket抽象层
  • 再经过传输层,网络层,链路层等。细节先省略。可以参照:网络通讯的的整体流程
    在这里插入图片描述
    Socket起源于UNIX,在UNIX“一切皆文件”的哲学思想下,Socket是一种从打开,到完成读、写操作,最后关闭的模式,服务器和客户端各自维护一个“文件”,在建立连接打开文件后,可以向自己的文件写入内容供对方读取或者读取对方的内容,通信结束时关闭文件。

I/O

用户进程中的一次完整I/O交互流程分为两阶段,首先是经过内核空间,也就是由操作系统处理;紧接着就是到用户空间,也就是交由应用程序。
在这里插入图片描述
通俗地将,可以将I/O分为两步:第一步是等待;第二步是数据搬迁。

阻塞I/O模型

阻塞I/O模型特点:在I\O执行的两个阶段(等待数据和拷贝数据)都被阻塞。
下图中红色部分都是阻塞。
典型应用:阻塞Socket、Java BIO
优点:阻塞挂起不消耗CPU资源
在这里插入图片描述

非阻塞I/O模型

相比较阻塞I/O,多了一个轮询访问内核是否存在。
典型应用:Socket设置NON_BLOCK
缺点:轮询调用,消耗CPU资源
在这里插入图片描述

多路复用I/O模型

多路复用I/O模型和阻塞I/O模型并没有太大的不同,事实上,还更差一些,因为这里需要使用两次系统调用(select和recvfrom),而阻塞I/O模型只有一次系统调用(recvfrom)。但是,用Selector的优势在于它可以同时处理多个连接,所以如果处理的连接数不是很多,多路复用I\O模型并不一定比使用多线程加阻塞I\O性能要好,可能延时更大。优势在于能处于更多的连接。
典型应用:Java NIO,Nginx(epoll,poll,select)
在这里插入图片描述

信号驱动I\O模型

信号驱动I/O是指进程预先告知内核,向内核注册一个信号处理函数,然后用户进程返回不阻塞,当内核数据就绪时会发送一个信号给进程,用户进程便在信号处理函数中调用I/O读取数据。
应用场景比较少。
在这里插入图片描述

异步I/O模型

工作机制:告知内核启动某个操作,并让内核在整个操作完成后通知我们。
与信号驱动I/O模型的区别:信号驱动I/O模型是由内核通知我们何时可以启动一个I/O操作,这个I/O操作由用户自定义的信号函数来实现,而异步I/O模型由内核告知我们I/O操作何时完成
典型应用:Java 7 AIO,高性能服务器应用
不阻塞,数据一步到位,采用Proactor模式
缺点:需要操作系统底层支持,Linux2.5内核首现 2.6产的内部标准特性
在这里插入图片描述

易于混淆的概念

  • 同步阻塞
  • 同步非阻塞
  • 异步阻塞
  • 异步非阻塞

同步和异步的区别:
同步:应用程序主动发起请求询问状态(轮询)
异步:服务方会主动通知请求方
在这里插入图片描述
阻塞和非阻塞的区别:
阻塞:等待返回数据之前,当前的线程是挂起状态
非阻塞:等待返回数据之前,当前的线程是运行状态,可以继续处理其他任务
在这里插入图片描述

列子:

(1)这个时候,如果我们一直在店里面什么都不干,一直等待直到洗完照片,这个过程就叫同步阻塞。
(2)当然,大部分人很少这么干,更多的是大家拿起手机开始看电视,看一会儿就会问老板洗完没,老板说没洗完,然后接着看,再过一会儿接着问,直到照片洗完,这个过程就叫同步非阻塞。
(3)由于店里生意太好了,越来越多的人过来拍,店里面快没地方坐了,老板说你把手机号留下,我一会儿洗好了就打电话告诉你过来取,然后你去外面找了一个长凳开始躺着睡觉等待老板打电话,什么都不干,这个过程就叫异步阻塞(实际不应用)。
(4)当然实际情况是,大家可能会先去逛街或者吃饭,或者做其他活动,这样一来,两不耽误,这个过程就叫异步非阻塞(效率最高)。

各I/O模型的对比与总结

阻塞程度:阻塞I/O>非阻塞I/O>多路复用I/O>信号驱动I/O>异步I/O,效率是由低到高的。
在这里插入图片描述

BIO、NIO、AIO

BIO:一个连接只用一个线程来处理。
NIO:单线程管理多个连接。缓冲区(Buffer)、选择器(Selector)和通道(Channel)
AIO:异步I/O,把I/O读写操作完全交给操作系统。操作系统主动通知实现异步。

BIO NIO AIO
面向流 面向缓冲区 操作系统主动通知用户线程
阻塞I\O 非阻塞I\O Proactor设计模式

参考资料
[1]: Netty 4核心原理与手写RPC框架实战

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章