同步阻塞式IO开发简单,但在处理IO密集的并发任务时,非常浪费CPU资源,性能低;并且,当一个进程(线程)含有多个套接字上时,同步阻塞式IO会带来问题:因为同步阻塞式IO只支持进程(线程)阻塞在一个套接字上,其余套接字上的事件将得不到及时处理。

为解决这些问题,IO编程的世界诞生了更多的IO模型及实现,这些实现不仅可以用在网络编程中,同样可以用在本地IO编程中。

在此先做说明,阻塞与非阻塞、同步与异步是两组不同的概念。

1.1         IO复用

IO 复用技术是指,调用IO 复用的api(select、pselect、poll、epoll等)时,其阻塞在多个文件描述符(套接字)上,这与普通的阻塞式IO函数如:read、write、close等不同,这些函数都是阻塞在一个文件描述符上。以select为例,select等待多个文件描述符(套接字)上发生IO事件,可以设置等待超时,select只返回描述符就绪的个数(一般可认为是IO事件的个数),用户需要遍扫描整个描述符集处理IO时间。伪代码如下:

while(true){

select(描述符集,超时值)

for(fd in 描述符集合){

if ( fd has IO事件){

处理IO事件

}

}

}

真实的select要比此复杂,其可指定自己关心的描述符集,分读、写、出错三种描述符集。

Select的缺点很明显,当描述符集很大时,遍历一遍集合的耗时将会很大,因此会有一个FD_SETSIZE宏限制。后续的epoll则优化的此问题,只返回发生的IO事件及其关联的描述符。

1.2         非阻塞IO(NIO)

非阻塞式IO与阻塞式IO不同的是,非阻塞式IO发现IO暂不可进行时,不阻塞,而是直接返回错误。可结合轮询构成一种可用的模型,但很少见。伪代码如下:

while(true) {

ret=recv(描述符)

if(ret != 错误 && ret != 结束){

处理IO事件

}

}

1.3         信号(事件)驱动IO

信号驱动式IO在IO事件就绪后,向用户程序发送信号或者直接执行回调(调用用户进程空间中的函数),用户在回调函数中执行IO处理。纵观各种读写的IO操作,都是首先等待内核准备好数据或准备好存放数据的内核空间,然后执行内核空间与用户进程空间之间的数据拷贝。其中,信号驱动式IO模型就是在内存做好准备之后,向用户进程发送信号,通知用户进程执行剩下的数据拷贝的操作。以读事件为例,过程如图:

可以看到,信号驱动模式中,读取数据时,依然使用的是同步IO。因此epoll可以说是一种同步非阻塞的支持IO多路复用的IO模型,但是在linux kernel 2.6版本之后,epoll使用了mmap(文件内存映射系统调用),使得数据从内核拷贝到用户进程空间的过程被省略了,于是它有了下面要讲的异步IO的特点,由此进一步产生了epoll到底是异步非阻塞还是同步非阻塞IO模型的一些争议。

1.4         异步IO(AIO)

异步IO与信号驱动IO模型,仅在于1、通知发生在数据从内核空间读取到用户空间(读)或者数据从用户空间写入到内核空间之后(写)。2、使用的是异步的系统调用api接口。以读为例,过程如图:

可以看到异步IO实在内核已完成IO操作之后,才发起通知,时机不同于信号(事件)驱动式IO。Linux中异步IO系统调用皆以aio_*开头。操作完成之后的通知方式可以是信号,也可以是用户进程空间中的回调函数,皆可通过aiocb结构体设置。目前linux 虽然已有aio函数,但是即使是epoll也并没有直接使用aio,而是通过非阻塞+mmap达到了伪AIO的效果,这与windows iocp和FreeBSD的kqueue纯异步的方案是不同的,普遍的测试结果,epoll性能比iocp还是有微小的差距。

高性能网络IO模型的更多相关文章

  1. IO模型及高性能网络架构分析

    前言 操作系统一次IO调用过程 应用程序发起的一次IO操作包含两个阶段: IO调用:应用程序进程向操作系统内核发起调用. IO执行:操作系统内核完成IO操作. 操作系统内核完成IO操作还包括两个过程: ...

  2. 框架篇:见识一下linux高性能网络IO+Reactor模型

    前言 网络I/O,可以理解为网络上的数据流.通常我们会基于socket与远端建立一条TCP或者UDP通道,然后进行读写.单个socket时,使用一个线程即可高效处理:然而如果是10K个socket连接 ...

  3. 服务器端网络编程之 IO 模型

    引言  从 T 跳槽到 A 之后,我的编程语言也从 C++ 转为 了 Java.在 T 做的偏服务器端开发,而在 A 更偏向于业务开发.上周在 A 公司组内做了一个<服务器端高性能网络编程> ...

  4. Netty学习之IO模型

    目录 1.1 同步.异步.阻塞.非阻塞     同步 VS 异步         同步         异步     阻塞 VS 非阻塞         阻塞         非阻塞     举例   ...

  5. 聊聊Netty那些事儿之从内核角度看IO模型

    从今天开始我们来聊聊Netty的那些事儿,我们都知道Netty是一个高性能异步事件驱动的网络框架. 它的设计异常优雅简洁,扩展性高,稳定性强.拥有非常详细完整的用户文档. 同时内置了很多非常有用的模块 ...

  6. 高性能IO模型浅析

    高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking  ...

  7. 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  8. Linux下常见的IO模型

    前言 阻塞IO(blocking IO) 非阻塞IO(nonblocking IO) IO复用(IO multiplexing) 异步IO(asynchronous IO (the POSIX aio ...

  9. IO模型

    前言 说到IO模型,都会牵扯到同步.异步.阻塞.非阻塞这几个词.从词的表面上看,很多人都觉得很容易理解.但是细细一想,却总会发现有点摸不着头脑.自己也曾被这几个词弄的迷迷糊糊的,每次看相关资料弄明白了 ...

随机推荐

  1. (NO.00002)iOS游戏精灵战争雏形(六)

    接下来我们给MainScene场景再添加一个精灵,作为敌人. 双击SpriteBuilder中的MainScene.ccb,从控件库拖入一个CCSprite到CCPhysicsNode中,设置精灵帧为 ...

  2. Asp.net中JQuery、ajax调用后台方法总结

    通过上一篇文章实例的实现,整个过程当中学习到很多知识点,了解了Jquery.Ajax在asp.net中的运用,加以总结,其实原理都是一样的,理解了一种,其他的注意很少的区别就可以了.灵活运用: 1.有 ...

  3. OC语言(六)

    四十六.block类型 用来封装代码,可以在任何时候执行. 与函数的区别:可以在运行时动态产生. block的标志:^ 有形参.有返回值 int (^sumblock)(int,int) = ^(in ...

  4. java反射案例详解

    白首为功名.旧山松竹老,阻归程.欲将心事付瑶琴.知音少,弦断有谁听? [案例1]通过一个对象获得完整的包名和类名 package Reflect; /** * 通过一个对象获得完整的包名和类名 * * ...

  5. Ubuntu快速截图

    以前截图,都是按Print键全屏截图,Alt+Print可以截当前的窗口.同时把系统自带的截图工具放到面板上,用的时候点击一下,再选择区域截图,很是不方便.不过,Ubuntu允许自己定义快捷键.要自己 ...

  6. 网络小白之WAN与LAN的区别

    剑指Offer--网络小白之WAN与LAN的区别 基本作用 wan接口是外网接口,是用来连接互联网或局域网等外部网络的. lan接口是内网接口,是用来连接计算机终端或其他路由器等终端设备的. 举例 w ...

  7. Android Studio环境下搭建ReactNative

    1.安装Android Studio首先肯定是 安装Android Studio(包含SDK)(国内推荐)ps:这里有一点要注意,需要为SDK配置环境变量,名称必须为ANDROID_HOME 2.安装 ...

  8. Oracle UTL_HTTP(收集汇总有用资料)

    From Oracle The UTL_HTTP package makes Hypertext Transfer Protocol (HTTP) callouts from SQL and PL/S ...

  9. Android特效专辑(八)——实现心型起泡飞舞的特效,让你的APP瞬间暖心

    Android特效专辑(八)--实现心型起泡飞舞的特效,让你的APP瞬间暖心 马上也要放年假了,家里估计会没网,更完这篇的话,可能要到年后了,不过在此期间会把更新内容都保存在本地,这样有网就可以发表了 ...

  10. 【LaTeX排版】LaTeX使用--入门基础<二>

    1.在命令之后留一个空格有下列方式: 源文件如下: \documentclass[a4paper,12pt]{book}%采用book类型(中篇论文一般采用这种类型),A4纸,字体为12磅,默认为10 ...