《Unix网络编程:卷1》中介绍了5中I/O模型,JAVA作为运行在宿主机上的程序,底层也遵循这5中I/O模型规则。这5中I/O模型分别是:

  • 阻塞式IO
  • 非阻塞式IO
  • I/O复用
  • 信号驱动式IO
  • 异步IO

按POSIX标准来分,IO分为同步和异步,上面的前4钟都属于同步IO,具体后面解释。

在介绍IO模型之前,需要先了解应用程序IO的过程,一般来说,一个IO分为两个阶段

应用程序向操作系统发出IO请求:应用程序发出IO请求给操作系统内核,操作系统内核需要等待数据就绪,这里的数据可能来自别的应用程序或者网络

  1. 等待数据:数据可能来自其他应用程序或者网络,如果没有数据,操作系统就一直等待,应用程序就跟着等待。
  2. 拷贝数据:将就绪的数据拷贝到应用程序工作区。

在Unix系统中,操作系统的IO操作是一个系统调用recvfrom(),即一个系统调用recvfrom包含两步,等待数据就绪和拷贝数据。

阻塞式IO模型

正如上面的IO操作的步骤,当应用程序发起IO请求之后,操作系统就要处理系统调用recvfrom(),在这个过程中,操作系统需要等待数据就绪(数据可能来自别的应用程序的输入或者网络),应用程序则不再处理别的事情,而是一直等待(即阻塞状态)数据就绪,然后操作系统完成IO操作,然后recvfrom()才方法返回,应用程序才继续执行,这就是阻塞式IO模型。下图描述了阻塞式IO模型

非阻塞式IO模型

当应用程序发起了IO请求之后,系统调用recvfrom()被执行,并且立即返回,但是返回的并不是IO处理完成的结果,而是一个特定的错误,表示IO数据没有准备好,因此不需要进行IO操作。应用程序会不停地(即轮询)执行recvfrom()系统调用,直到数据已经就绪,然后操作系统完成IO操作,recvfrom()返回成功。这个过程中,没有数据就绪时系统调用recvfrom()是立即返回的,即应用程序并没有阻塞在底层操作系统的等待数据上面,而是轮询结果。这个过程可以用下图表示,

可见阻塞IO与非阻塞IO的关键区别在于,系统调用recvfrom是否立即返回。由于轮询会消耗大量CPU时间,因此这种模式并不常用。

IO复用模型(多路复用)

前面的非阻塞IO将会轮询一个IO是否可用,而IO复用则是轮询多个IO是否至少有一个可用。

IO复用的关键在于select()函数。在阻塞IO中,应用程序阻塞在一个IO的内核操作上;

但在多路复用中,通过select(),可以同时监听多个IO请求的内核操作,只要有任意一个IO的内核操作就绪,都可以通知select()返回,再进行系统调用recvfrom()完成IO操作。

这个过程应用程序就可以同时监听多个IO请求,这比起基于多线程阻塞式IO要先进得多,因为服务器只需要一两个线程就可以进行多客户端通信。IO复用可用下图表示,

信号驱动式IO模型

在unix系统中,应用程序发起IO请求时,可以给IO请求注册一个信号函数,请求立即返回,操作系统底层则处于等待状态(等待数据就绪),直到数据就绪,然后通过信号通知主调程序,主调程序才去调用系统函数recvfrom()完成IO操作。

信号驱动也是一种非阻塞式的IO模型,比起上面的非阻塞式IO模型,信号驱动式IO模型不需要轮询检查底层IO数据是否就绪,而是被动接收信号,然后再调用recvfrom执行IO操作。

比起多路复用IO模型来说,信号驱动IO模型针对的是一个IO的完成过程, 而多路复用IO模型针对的是多个IO同时进行时候的场景。 信号驱动式IO模型用下图表示,

异步IO模型

异步IO模型的工作机制是,将整个IO操作(包括等待数据就绪,复制数据到应用程序工作空间)全都交给操作系统完成,操作系统完成整个过程之后,再通知应用程序。

异步IO模型跟信号驱动IO模型很相似,但是区别是信号驱动模型是在数据就绪的时候通知应用程序,应用程序再调用系统函数recvfrom进行IO操作。

而异步IO模型则是数据就绪且操作系统已经将数据拷贝进应用程序运行空间之后,操作系统再通知应用程序,这个过程中应用程序不需要阻塞。异步IO可以如下图表示,

IO模型对比

可见前面四种IO模型中,应用程序都会在某一环节阻塞(即使是轮询,也算是一种阻塞),POSIX将这种IO模型称为同步IO操作,

而异步IO模型,则是全权把IO操作整个过程都交给操作系统,中途无阻塞,POSIX将这种IO模型称为异步IO操作。  以上所有IO对比如下图,

JAVA基础知识之网络编程——-网络通信模型(IO模型)的更多相关文章

  1. JAVA基础知识之面向对象编程知识汇总

    JAVA基础课程部分面向对象已经学习完成,知识结构如下: 总体知识框架: 类的结构: 面向对象编程三大特征: 关键字和抽象类接口等: 常见知识汇总: 成员变量和局部变量比较 有无返回值方法比较: 权限 ...

  2. JAVA基础知识总结17(网络编程)

    端口: 物理端口:IP地址 逻辑端口:用于标识进程的逻辑地址,不同进程的标识:有效端口:0~65535,其中0~1024系统使用或保留端口. JAVA中ip对象:InetAddress. import ...

  3. JAVA基础知识之JDBC——编程步骤及执行SQL

    JDBC编程步骤 下面以mysql数据库为例, 1.加载驱动 首先需要下载数据库的驱动jar文件,并且在eclipse包中加入到class path中去, 例如mysql的驱动文件 mysql-con ...

  4. JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)

    本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...

  5. Java基础复习笔记系列 九 网络编程

    Java基础复习笔记系列之 网络编程 学习资料参考: 1.http://www.icoolxue.com/ 2. 1.网络编程的基础概念. TCP/IP协议:Socket编程:IP地址. 中国和美国之 ...

  6. [转] - Linux网络编程 -- 网络知识介绍

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  7. java基础知识精华

    转载:https://www.jianshu.com/p/6c078abb720f java基础知识 java内存模型 java运行时数据区域 hashMap 如何解决冲突 存储方式 冲突达到一定数量 ...

  8. 学习Spring必学的Java基础知识(1)----反射(转)

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  9. 学习Spring必学的Java基础知识(1)----反射

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系 ...

  10. Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

随机推荐

  1. Oracle临时表

    1概念理解 ORACLE系统的临时表常被用于存放系统操作的中间数据,由于对临时的任何操作都不产生redo(但会因为修改undo而产生redo),所以临时表的数据操作效率一般都比较高.常用的临时表主要有 ...

  2. iOS Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:7962

      Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Cac ...

  3. IOS第12天(1,UIViewController控制器的创建的 三种方式,和第一个view创建)

    *************HMAppDelegate.m中 @implementation HMAppDelegate - (BOOL)application:(UIApplication *)app ...

  4. CSS权威指南 - 基础视觉格式化 3

    行内替换元素 替换元素比如图片的高度比line-height大,并不会影响整个文字段落的line-height,会让有图片那一行框的高度可以容纳这个图片. 这个图片依然有一个line-height,和 ...

  5. ssh secure shell

    ssh secure shell 和securecrt xhell一样,都是终端工具

  6. ios-改变button四个角的弧度

    -(void)createTitleView{ UIView * backview = [[UIView alloc]init]; backview.frame =CGRectMake(87*kHei ...

  7. GDC2016 [全境封锁],11个种类5个派系的敌人设计思路

    [汤姆克兰西:全境封锁],11个种类5个派系的敌人设计思路 实现[汤姆克兰西]射击RPG的AI开发   日文链接:http://game.watch.impress.co.jp/docs/news/2 ...

  8. C# 模拟鼠标移动与点击

    我们需要用到的mouse_event函数,位于user32.dll这个库文件里面,所以我们要先声明引用. [System.Runtime.InteropServices.DllImport(" ...

  9. 【java基础学习】GUI

    GUI 容器 布局管理器 组件 菜单 事件处理机制

  10. 求解PDE的多重网格法(MG)

    多重网格法相对于普通的Jacobi迭代或者G-S迭代等能够得到和未知数的个数成线性的高效运行时间的主要原因在于:迭代初值的一步步接近真值和G_S方法的前面几步的快速收敛性. 先看一张图[1]: 这张图 ...