四种IO模型学习介绍

一. 常见IO模型介绍

        同步阻塞IO (Blocking IO)

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

        IO 多路复用 (IO Multiplexing)

        异步IO (Asynchronous IO)

二. 介绍

        1. 同步阻塞IO (Blocking IO)

                什么是阻塞与非阻塞

                        阻塞IO, 指的是需要内核IO操作彻底完成后,才返回到用户空间,执行用户的操作。

                        阻塞指的是用户控件程序的执行状态,用户控件程序需等到IO 操作彻底完成。

                        传统的IO模型都是同步阻塞IO。 在Java中,默认创建的Socket都是阻塞的。

                什么是异步与同步

                        同步IO,是一种用户空间和内核空间的调用发起方式。

                        同步IO指用户空间线程是主动发起IO请求的乙方,内核空间是被动接受方。

                        异步IO则相反,指内核Kernel是主动发起IO请求的乙方,用户线程是被动接受方。

                大概流程

                        a. 用户线程调用read系统调用,内核(Kernel) 开始了IO的第一个阶段:准备数据。(需要等待一个完成的Socket数据包)

                        b. 内核等待数据准备完成,将数据从内核缓冲区,拷贝到用户缓冲区(用户内存),然后返回结果

                        c. 当开始IO读的read系统调用开始,用户线程就进入阻塞状态。一直到内核返回结果后,用户线程才接触Block状态,重新运行起来

                        Blocking IO的特点就是内核进行IO执行的两个阶段,用户线程都被Block了。

                优缺点

                        优点:程序相对简单,在阻塞等待数据期间,用户线程被挂起。用户线程基本不会占用CPU资源。

                        缺点:会为每个连接配套一条独立的线程,或者说是一条线程维护一个连接成功的IO流的读写。在高并发的场景下,需要大量的线程来维护大量的网络连接,内存,线程切换开销巨大,可用效率低下。

        2.同步非阻塞NIO(Non-nlocking IO)

                定义

                        指得失用户程序不需要等待内核IO操作完成后,内核立即返回给用户一个状态值,用户空间无需等到内核的IO操作彻底完成,可以立即返回给用户空间,执行用户的操作,处于非阻塞的状态。

                        非阻塞IO要求Socket被设置为NONBLOCK。

                        注意这的 NIO(同步非阻塞IO)模型,并非Java的NIO(New IO)库。

                大概流程

                        a. 在内核数据没有准备好的阶段,用户线程发起IO请求时,立即返回。用户线程需要不断地发起IO系统调用。

                        b. 内核数据到达后,用户线程发起系统调用,用户线程阻塞。内核开始复制数据。将数据从内核缓冲区,拷贝到用户空间,然后返回结果。

                        c. 用户线程拿到结果才解除block的状态,重新运行起来。

                优缺点

                        优点:每次的IO系统调用,在内核的等待数据过程中可以立即返回。用户线程不会阻塞,实用性较好。

                        缺点: 需要不断的重复发起IO系统调用,不断的轮询内核,会占用大量的CPU时间,系统资源利用率较低。

                        由于不断轮询的特点,在高并发的场景下也不可用。很少使用这种模型。

                        注意: 该模型不是JAVA NIO (New IO) ,那是另一种模型,名为IO多路复用。

       3. IO多路复用模型(I/O Multiplexing)

                 解释

                        IO多路复用模型,通过一种新的系统调用,一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读/可写), 内核能够通知程序经此能够相应的IO系统调用。

                大概流程

                        在该种模型中, 首先不是进行read系统调动,而是进行select/epoll 系统调用。 有一个前提,需要将目标网络连接,提前注册到select/epoll的可查询socket列表中。然后才能开启整个IO多路复用模型的读流程。

                        a. 进行select/epoll 系统调用,查询可以读的连接。内核会查询所有select的可查询socket列表,当任何一个socket中的数据准备好了,select就会返回。当用户进程调用了select,那么整个线程会被block。

                        b. 用户线程获得了目标连接后,发起read系统调用,用户线程阻塞。内核开始复制数据。将数据从内核缓冲区,拷贝到用户缓冲区(用户内存),然后内核返回结果。

                        c. 用户线程得到内核返回的结果才会解除block的状态,用户线程真正读取到数据,继续执行。

                优缺点

                        优点: select/epoll优势在于,能够同时处理成千上万个连接。与一条线程维护一个连接相比,I/O多路复用技术的最大优势是:系统不必创建线程,也不必维护这些线程,大大减小了系统的开销。

                                Java 的NIO技术,使用的就是 IO多路复用模型。

                        缺点: select/epoll系统的调用,属于同步IO,也是阻塞IO。 都需要再度些时间就绪后,自己负责进行读写,这个读写过程是阻塞的。

                        特点:建立在操作系统内核能够提供的多路分离系统调用select/epoll基础之上的。多路复用IO需要用到两个系统调用,select/epoll 查询调用, IO的读取调用。

                                多路复用 IO需要轮询,负责select/epoll查询调用的线程,要不断地进行select/epoll轮询,查找出可以进行IO操作的连接。

                                对于每一个可以查询的socket,一般都设置成为non-blocking 模型,这一点对于用户程序是透明的(不感知)。

        4.异步IO模型(Asynchronous IO)

                定义

                        异步IO,指的是用户空间与内核空间的调用方式反过来。用户空间线程是变成被动接受的,内核空间是主动调用者。 简称 AIO

                 大概流程

                        a. 用户线程调用了read系统调用,立刻可以开始做其他事情,用户线程不在阻塞。

                        b. 内核开始IO的第一个姐u但:准备数据。当内核以后i等到数据准备好,会将数据从内核缓冲区,拷贝到用户缓冲区(用户内存)。

                        c. 内核会给用户线程发送一个个信号(Signal),或者回调用户线程注册的回调接口,考试用户线程read操作完成了

                        d. 用户线程读取用户缓冲区的数据,完成后续的业务操作。

                优缺点

                        优点:在内核的等待数据和复制数据的两个阶段,用户线程都不是block(阻塞) 的。用户线程需要接收内核的IO操作完成的事件,或者说注册IO操作完成的回调函数,到操作系统的内核。 异步IO 有时候也叫做信号驱动 IO。

                        缺点:需要完成事件的注册与传递,需要底层操作系统提供大量的支持,做大量的工作。  (目前并不完善)

三.总结

        四种IO模型,理论上越往后,阻塞越少,效率也是最优。在这四种 I/O 模型中,前三种属于同步 I/O,因为其中真正的 I/O 操作将阻塞线程。只有最后一种,才是真正的异步 I/O 模型,目前Linux 操作系统尚欠完善。

学习内容借鉴什么是NIO?10分钟带你看懂IO和NIO底层原理_io nio_程序猿七度的博客-CSDN博客

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值