netty学习(一)IO模型

 

  1.引言

  网络IO模型一般分为同步,异步,阻塞,非阻塞,多路复用等。在学习各种IO模型前,我们先来理清这几种概念。

  2.同步与异步,阻塞与非阻塞

   同步与异步是针对应用程序与内核的交互而言的。同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成。

  阻塞与非阻塞简单理解为需要做一件事能不能立即得到返回应答,如果不能立即获得返回,需要等待,那就阻塞了,否则就可以理解为非阻塞。

  

  同步阻塞IO:在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!

  同步非阻塞IO:在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。

  异步阻塞IO:此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!

  异步非阻塞IO:在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。

  3.多路复用

  对于多路复用,也就是轮询多个socket。多路复用既然可以处理多个IO,也就带来了新的问题,多个IO之间的顺序变得不确定了,当然也可以针对不同的编号。具体流程,如下图所示:

 netty学习(一)IO模型_第1张图片

  其中java.nio.channels.Selector是Java非阻塞IO实现的关键,这里的非阻塞不是指select系统调用时非阻塞的,当内核态执行系统调用时,如果此时没有socket连接,也就是没有数据写入,此时select系统调用是阻塞的,直到有socket连接,但是select可以同时处理很多的socket连接,所以被称为非阻塞IO,所以多路复用IO可以在一个线程中处理多个并发的连接。

  这种模型提供了更好的资源管理:

    1:使用较少的线程可以处理许多连接,因此也加少了内存管理和上下文切换所带来的开销;

    2:当没有IO操作需要处理的时候,线程也可以被用于其它任务,充分利用现有的空闲线程。

你可能感兴趣的:(netty)