四种 IO 模型:
 
    首先需要明确,IO发生在 用户进程 与 操作系统 之间。可以是客户端IO也可以是服务器端IO。
  • 阻塞IO(blocking IO):
    在linux中,默认情况下所有socket都是blocking:kernel和用户都在阻塞等待数据。

 
  • 非阻塞IO(non-blocking):
       用户程序重复调用系统调用 recvfrom ,等待 return OK信号。 polling轮询

        为什么没有Block:用户进程发出read请求后 ,如果kernel中的数据还没有准备好,那么就会立即返回来一个error信号。对于用户角度来讲他并没有等待,而是立即就得到了一个结果。接下来,用户进程就会不断主动询问kernel有没有准备好。
 
 
  • IO多路复用(IO multiplexing)
    常用的方法就是 select 和 epoll 。这种方法也和叫作 事件驱动IO
这种方式的好处在于:kernel的单个process可以同时处理多个网络连接IO。将轮询的工作统一交给kernel内核监管的函数select/epoll(该函数由用户态 调用,kernel监管)函数。用户可以将多个socket注册到同一个select中,kernel来监管select中注册的IO,一旦发任何一个socket现数据准备好了,就将通知用户process,调用read将数据从kernel拷贝到用户进程。这样用户process就从轮询中解放出来,只需要静静地等待select函数返回即可。当然,这个过程中,用户也是block的,虽然是block的(被select block) 但是什么都不做的block和不断去 “轮询”的block,还是不同的!这样可以减少用户process的负担。
 
这里就要插入另外一个内容:select、poll、epoll
 
select主要的缺陷有三个:
1)最大并法数限制:受限于一个进程能够打开的FD(文件描述符)的个数。在linux/posix_types.h头文件有这样的声明:#define __FD_SETSIZE    1024  表示select最多同时监听1024个,因此最大并发数就被限制了。
2)效率问题:select每次都会线性扫描【类似数组来存储】全部的FD集合,这样效率就会呈线形下降。
3)内核/用户空间内存拷贝。
 
poll 基本等于select 后两点都没有改善
 
epoll 
  1. int epoll_create(int size);
  2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
  3. int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
 
对比select 就有如下优点:
1)   最大并发数不受限制。上限是:当前系统中打开文件的最大数目。
2)效率高。因为epoll只管当前活跃的socket,epoll维护一颗红黑树。那些注册了的socket或者说是文件描述符,就会高效的在树上插入或者删除。
        epoll的高效就在于(引用):“epoll_ctl往里塞入百万个句柄时,epoll_wait仍然可以飞快的返回,并有效的将发生事件的句柄给我们用户。这是由于我们在调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个红黑树用于存储以后epoll_ctl传来的socket外,还会再建立一个list链表,用于存储准备就绪的事件,当epoll_wait调用时,仅仅观察这个list链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait非常高效。
        而且,通常情况下即使我们要监控百万计的句柄,大多一次也只返回很少量的准备就绪句柄而已,所以,epoll_wait仅需要从内核态copy少量的句柄到用户态而已,如何能不高效?!
        那么准备就绪的列表list是怎么维护的呢?当我们执行epoll_ctl的时候,除了把socket放到epoll文件系统里file对应的红黑树上之外,还会在内核的中断处理程序上注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到准备就绪的list中,也就是当socket有数据到达后,内核会把网卡上的数据copy到内核中后就把socket插入到准备列表list中。”
        最后,总结一下:
1 当用户调用epoll_create后,内核会在内存cache中创建一个红黑树就绪列表
2 当用户调用epoll_ctl注册 socket(文件句柄)时,内核会在红黑树上查找是否有该句柄。如果存在,则立即返回。如果没有,那么在红黑树的节点上增加,然后在内核注册回调函数,用于当中断来临的时候,向中断就绪链表中插入数据。
3 当用户调用epoll_wait时,立即返回就绪列表中的数据。
 
关于epoll的LT(水平触发)和ET(边缘触发)两种工作模式:
LT:只要改句柄上的事件没有处理完,那就此此返回。
ET:只返回一次。
实现的原理在于对list就绪列表的清空机制上。清空后,如果是LT且未处理完,就再放回到就绪列表中。
 
 
 
 
 
  • 异步IO(Asynchronous IO)

    用户发起read之后,服务器端kernel会立刻返回。用户process就会去做其他事情去了。这种情况下,对于服务器来说,接收到每一个IO请求都需要开辟一个线程去专门去处理。
3)用户与内核共享内存,no more 内存拷贝。
 
######################################################################################
最后说一说,
 
1)阻塞Block与非阻塞Nonblock的区别:
        Block会让用户进程Block住直到请求的IO操作完成;NonBlock会在kernel正在准备数据的时候,立即返回一个结果,知道这个结果是OK就绪信号,那么接下来进程读取数据,done;
 
2)同步synchronous与异步asynchronous的区别:
首先定义:
A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;
An asynchronous I/O operation does not cause the requesting process to be blocked; 
        上面所讲的block IO 、Non—block IO、IO 多路复用都属于 同步IO。Non-block 与其他方式一样,这里所说的block是当发生IO operation的时候,也就是调用 recv_from系统调用时,会发生block,以完成数据从内核态copy到用户态的过程。以上三种方式都是会block的。而asynchronous IO则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block。

各个IO Model的比较如图所示:

 
 

最后,再举几个不是很恰当的例子来说明这四个IO Model:
有A,B,C,D四个人在钓鱼:
A用的是最老式的鱼竿,所以呢,得一直守着,等到鱼上钩了再拉杆;
B的鱼竿有个功能,能够显示是否有鱼上钩,所以呢,B就和旁边的MM聊天,隔会再看看有没有鱼上钩,有的话就迅速拉杆;
C用的鱼竿和B差不多,但他想了一个好办法,就是同时放好几根鱼竿,然后守在旁边,一旦有显示说鱼上钩了,它就将对应的鱼竿拉起来;
D是个有钱人,干脆雇了一个人帮他钓鱼,一旦那个人把鱼钓上来了,就给D发个短信。

参考:http://blog.csdn.net/fuyuehua22/article/details/38304495

    

四种IO模型的更多相关文章

  1. 图解四种 IO 模型

    最近越来越认为,在讲解技术相关问题时,大白话固然很重要,通俗易懂,让人有想读下去的欲望.但几乎所有的事,都有两面性,在看到其带来好处时,不妨想想是否也引入了不好的地方. 例如在博客中,过于大白话的语言 ...

  2. Linux五种IO模型(同步 阻塞概念)

    Linux五种IO模型 同步和异步 这两个概念与消息的通知机制有关. 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.比如,调用readfrom系统调用时,必须等待IO操 ...

  3. 漫谈五种IO模型

    阅读目录 1 基础知识回顾 2 I/O模式 3 事件驱动编程模型 网络编程里常听到阻塞IO.非阻塞IO.同步IO.异步IO等概念,搞清楚这些概念之前,还得先回顾一些基础的概念. 1 基础知识回顾 注意 ...

  4. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  5. Linux 网络编程的5种IO模型:异步IO模型

    Linux 网络编程的5种IO模型:异步IO模型 资料已经整理好,但是还有未竟之业:复习多路复用epoll 阅读例程, 异步IO 函数实现 背景 上一讲< Linux 网络编程的5种IO模型:信 ...

  6. 正确理解这四个重要且容易混乱的知识点:异步,同步,阻塞,非阻塞,5种IO模型

    本文讨论的背景是Linux环境下的network IO,同步IO和异步IO,阻塞IO和非阻塞IO分别是什么 概念说明 在进行解释之前,首先要说明几个概念: - 用户空间和内核空间 - 进程切换 - 进 ...

  7. (四)五种IO模型

    基本概念 我们之前编写的套接字程序都是阻塞式的,其实这也是默认的形式.现在我们需要明确一些概念: 用户空间和内核空间 首先要明确,用户启动的应用程序在系统中以一个进程的形式存在,而无论对于网络数据还是 ...

  8. Atitit  五种IO模型attilax总结 blocking和non-blocking synchronous IO和asynchronous I

    Atitit  五种IO模型attilax总结 blocking和non-blocking synchronous IO和asynchronous I   1.1. .3 进程的阻塞1 1.2. 网络 ...

  9. 聊聊 Linux 中的五种 IO 模型

    本文转载自: http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666538919&idx=1&sn=6013c451 ...

随机推荐

  1. Devu and Flowers lucas定理+容斥原理

    Devu wants to decorate his garden with flowers. He has purchased n boxes, where the i-th box contain ...

  2. 洛谷——P1454 圣诞夜的极光

    P1454 圣诞夜的极光 题目背景 圣诞夜系列~~ 题目描述 圣诞老人回到了北极圣诞区,已经快到12点了.也就是说极光表演要开始了.这里的极光不是极地特有的自然极光景象.而是圣诞老人主持的人造极光. ...

  3. litepal创建数据库表失败

    今天学习郭神的litepal框架遇到了一个坑,就是程序正常跑了,但是数据库和表完全没创建!!!!!!! 先核对了litepal.xml文件,确认配置正确,assets文件夹放的也正确,最后发现竟然是因 ...

  4. spring 数据源JNDI 基于tomcat mysql配置

    关键代码 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean&q ...

  5. neutron trouble shooting - ip can not ping

    neutron创建了一个router后,显示列表如下: [root@controller01 keystone]# neutron router-port-list router +--------- ...

  6. openstack setup demo Overview

    Overview openstack是一套开源的云计算部署平台,通过一系列service提供IAAS.每一个service都提供API.具体的service列表如下: dashboard Horizo ...

  7. STL中常用的c++语法

    函数调用操作(c++语法中的左右小括号)可以被重载,STL的特殊版本都以仿函数形式呈现.如果对某个class进行operator()重载,它就成为一个仿函数. 仿函数(functor),就是使一个类的 ...

  8. Cocos2d-x v3.1.1 创建以及编译项目

    1.安装python, 并将安装路径增加系统环境变量中; 2. 执行cocos2d-x根文件夹下的setup.py; 3. 进入cmd, 输入: cocos new 项目名称 -p 包名 -l 语言类 ...

  9. 小工具:天气查询 Vs自定义设置 DevGridControl中GridView排序问题 小工具:火车票查询 小工具:邮件发送 小工具:截图&简单图像处理

    小工具:天气查询   开发一个天气查询的工具主要由两步构成,一是数据的获取,二是数据的展示.  一.数据获取 数据获取又可以分为使用其它公司提供的API和手动抓取其它网站数据. 1. 某公司提供的AP ...

  10. org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not

    遇到这个问题之前,我去百度和谷歌去搜索了一下.发现各种说法.可是针对我的项目而言,也就是公司的项目而言,这个问题的根源并不是是网上所说的那样. 最后是通过自己的想法做測试得到了解决. 1.首先说说我的 ...