目录

一、Linux I/O 模型

1.I/O模型分类

2.I/O模型的相关术语

二、Linux I/O 模型具体说明

1.阻塞I/O

2.非阻塞I/O

3.I/O复用(select和poll)

4.信号驱动I/O(SIGIO)

5.异步I/O(Posix.1的aio_系列函数)

6.I/O 模型总结(如下图)

三、Linux I/O模型的具体实现

1.主要实现方式有以下几种:

2.为什么epoll、kqueue、/dev/poll比select高级?

3.Windows or *nix (IOCP or kqueue、epoll、/dev/poll)?

4.总结一些重点


一、Linux I/O 模型

1.I/O模型分类

说明:我们都知道web服务器的进程响应用户请求,但无法直接操作I/O设备,其必须通过系统调用,请求kernel来协助完成I/O动作,内核会为每个I/O设备维护一个buffer,如下图:

对于数据输入而言,即等待(wait)数据输入至buffer需要时间,而从buffer复制(copy)数据至进程也需要时间。

根据等待模式不同,I/O动作可分为五种模式。

  • 阻塞I/O
  • 非阻塞I/O
  • I/O复用(select和poll)
  • 信号(事件)驱动I/O(SIGIO)
  • 异步I/O(Posix.1的aio_系列函数)

2.I/O模型的相关术语

这里有必要先解释一下阻塞、非阻塞,同步、异步、I/O的概念。

(1).阻塞和非阻塞

阻塞和非阻塞指的是执行一个操作是等操作结束再返回,还是马上返回。比如你去车站接朋友,这是一个操作。可以有两种执行方式。第一种,你这人特实诚,老早就到了车站一直等到车来了接到朋友为止。第二种,你到了车站,问值班的那趟车来了没有,“还没有”,你出去逛一圈,可能过会回来再问。第一种就是阻塞方式,第二种则是非阻塞的。我认为阻塞和非阻塞讲得是做事方法,是针对做事的人而言的。

(2).同步和异步

同步和异步又是另外一个概念,它是事件本身的一个属性。比如老板让你去搬一堆石头,而且只让你一个人干,你只好自己上阵,最后的结果是搬完了,还是你砸到脚了,只有搬完了你才知道。这就是同步的事件。如果老板还给你个小弟,你就可以让小弟去搬,搬完了告你一声。这就变成异步的了。其实异步还可以分为两种:带通知的和不带通知的。前面说的那种属于带通知的。有些小弟干活可能主动性不是很够,不会主动通知你,你就需要时不时的去关注一下状态。这种就是不带通知的异步。

对于同步的事件,你只能以阻塞的方式去做。而对于异步的事件,阻塞和非阻塞都是可以的。非阻塞又有两种方式:主动查询和被动接收消息。被动不意味着一定不好,在这里它恰恰是效率更高的,因为在主动查询里绝大部分的查询是在做无用功。对于带通知的异步事件,两者皆可。而对于不带通知的,则只能用主动查询。

(3).I/O

回到I/O,不管是I还是O,对外设(磁盘)的访问都可以分成请求和执行两个阶段。请求就是看外设的状态信息(比如是否准备好了),执行才是真正的I/O操作。在Linux 2.6之前,只有“请求”是异步事件,2.6之后才引入AIO把“执行”异步化。别看Linux/Unix是用来做服务器的,这点上比Windows落后了好多,IOCP(Windows上的AIO)在Win2000上就有了,呵呵。

(4).总结

Linux上的前四种I/O模型的“执行”阶段都是同步的,只有最后一种才做到了真正的全异步。第一种阻塞式是最原始的方法,也是最累的办法。当然累与不累要看针对谁。应用程序是和内核打交道的。对应用程序来说,这种方式是最累的,但对内核来说这种方式恰恰是最省事的。还拿接人这事为例,你就是应用程序,值班员就是内核,如果你去了一直等着,值班员就省事了。当然现在计算机的设计,包括操作系统,越来越为终端用户考虑了,为了让用户满意,内核慢慢的承担起越来越多的工作,IO模型的演化也是如此。

非阻塞I/O ,I/O复用,信号驱动式I/O其实都是非阻塞的,当然是针对“请求”这个阶段。非阻塞式是主动查询外设状态。I/O复用里的select,poll也是主动查询,不同的是select和poll可以同时查询多个fd(文件句柄)的状态,另外select有fd个数的限制。epoll是基于回调函数的。信号驱动式I/O则是基于信号消息的。这两个应该可以归到“被动接收消息”那一类中。最后就是伟大的AIO的出现,内核把什么事都干了,对上层应用实现了全异步,性能最好,当然复杂度也最高。好了,下面我们就来详细说一说,这几种模式。


二、Linux I/O 模型具体说明

首先,我们先来看一下,基本 Linux I/O 模型的简单矩阵,

从图中我们可以看到的模型有,同步阻塞I/O(阻塞I/O)、同步非阻塞I/O(非阻塞I/O )、异步阻塞I/O(I/O复用),异步非阻塞I/O(有两种,信号驱动I/O和异步I/O)。好了现在就来具体说一说吧。

1.阻塞I/O

说明:应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。 如果数据没有准备好,一直等待数据准备好了,从内核拷贝到用户空间,IO函数返回成功指示。这个不用多解释吧,阻塞套接字。

下图是它调用过程的图示:(注,一般网络I/O都是阻塞I/O,客户端发出请求,Web服务器进程响应,在进程没有返回页面之前,这个请求会处于一直等待状态)

2.非阻塞I/O

我们把一个套接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。这样我们的I/O操作函数将不断的测试数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间,所有一般Web服务器都不使用这种I/O模型。具体过程如下图:

3.I/O复用(select和poll)

I/O复用模型会用到select或poll函数或epoll函数(Linux2.6以后的内核开始支持),这两个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。具体过程如下图:

4.信号驱动I/O(SIGIO)

首先,我们允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。具体过程如下图:

5.异步I/O(Posix.1的aio_系列函数)

当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。具体过程如下图:

6.I/O 模型总结(如下图)

从上图中我们可以看出,可以看出,越往后,阻塞越少,理论上效率也是最优。其五种I/O模型中,前三种属于同步I/O,后两者属于异步I/O。

同步I/O:

  • 阻塞I/O
  • 非阻塞I/O
  • I/O复用(select和poll)    

异步I/O:

  • 信号驱动I/O(SIGIO) (半异步)
  • 异步I/O(Posix.1的aio_系列函数)(真正的异步)

异步 I/O 和 信号驱动I/O的区别:

  • 信号驱动 I/O 模式下,内核可以复制的时候通知给我们的应用程序发送SIGIO 消息。
  • 异步 I/O 模式下,内核在所有的操作都已经被内核操作结束之后才会通知我们的应用程序。

OK,5种模型的比较比较清晰了,下面我们来说一下五种模型的具体实现。


三、Linux I/O模型的具体实现

1.主要实现方式有以下几种:

  • select
  • poll
  • epoll
  • kqueue
  • /dev/poll
  • iocp

注:其中iocp是Windows实现的,select、poll、epoll是Linux实现的,kqueue是FreeBSD实现的,/dev/poll是SUN的Solaris实现的。select、poll对应第3种(I/O复用)模型,iocp对应第5种(异步I/O)模型,那么epoll、kqueue、/dev/poll呢?其实也同select属于同一种模型,只是更高级一些,可以看作有了第4种(信号驱动I/O)模型的某些特性,如callback机制。

2.为什么epoll、kqueue、/dev/poll比select高级?

答案是,它们无轮询。因为他们用callback取代了。想想看,当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll、kqueue、/dev/poll做的。

这样子说可能不好理解,那么我说一个现实中的例子,假设你在大学读书,住的宿舍楼有很多间房间,你的朋友要来找你。select版宿管大妈就会带着你的朋友挨个房间去找,直到找到你为止。而epoll版宿管大妈会先记下每位同学的房间号,你的朋友来时,只需告诉你的朋友你住在哪个房间即可,不用亲自带着你的朋友满大楼找人。如果来了10000个人,都要找自己住这栋楼的同学时,select版和epoll版宿管大妈,谁的效率更高,不言自明。同理,在高并发服务器中,轮询I/O是最耗时间的操作之一,select、epoll、/dev/poll的性能谁的性能更高,同样十分明了。

3.Windows or *nix (IOCP or kqueue、epoll、/dev/poll)?

诚然,Windows的IOCP非常出色,目前很少有支持asynchronous I/O的系统,但是由于其系统本身的局限性,大型服务器还是在UNIX下。而且正如上面所述,kqueue、epoll、/dev/poll 与 IOCP相比,就是多了一层从内核copy数据到应用层的阻塞,从而不能算作asynchronous I/O类。但是,这层小小的阻塞无足轻重,kqueue、epoll、/dev/poll 已经做得很优秀了。

4.总结一些重点

  • 只有IOCP(windows实现)是asynchronous I/O,其他机制或多或少都会有一点阻塞。
  • select(Linux实现)低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善
  • epoll(Linux实现)、kqueue(FreeBSD实现)、/dev/poll(Solaris实现)是Reacor模式,IOCP是Proactor模式。
  • Apache 2.2.9之前只支持select模型,2.2.9之后支持epoll模型
  • Nginx 支持epoll模型
  • Java nio包是select模型

愿你就像早晨八九点钟的太阳,活力十足,永远年轻。

Nginx系列(5):Web服务器分析之Linux I/O(理论中)相关推荐

  1. linux主流的web服务器,适合Web服务器的非主流Linux发行版

    适合Web服务器的非主流Linux发行版 在众多的Linux发行版中有很多是大家不熟悉,这些偏离主流的发行版有很多都可以应用在Web服务器上面.下面我们就来看看相关的非主流Linux发行版.在这里我们 ...

  2. Nginx+Tomcat构筑Web服务器集群

    代理服务 代理服务可简单的分为正向代理和反向代理: 正向代理: 用于代理内部网络对Internet的连接请求(如VPN/NAT),客户端指定代理服务器,并将本来要直接发送给目标Web服务器的HTTP请 ...

  3. Nginx+Keepalived实现Web服务器负载均衡

    说明: 操作系统:CentOS 5.X 64位 Web服务器:192.168.21.127.192.168.21.128 站点:bbs.osyunwei.com和sns.osyunwei.com部署在 ...

  4. Nginx搭建部署Web服务器并与NFS结合搭建负载均衡服务器

    Nginx搭建部署Web服务器并与NFS结合搭建负载均衡服务器 一.搭建NginxWeb服务器     此种方式是用yum安装Nginx,为保证安装成功需在安装之前提前安装epel扩展源.     用 ...

  5. dump文件分析工具_使用这个 Python 工具分析你的 Web 服务器日志文件 | Linux 中国...

    导读:这个 Python 模块可以以多种格式收集网站使用日志并输出良好结构化数据以进行分析. 本文字数:3262,阅读时长大约:4分钟https://linux.cn/article-12512-1. ...

  6. asp.net core 系列 18 web服务器实现

    一. ASP.NET Core Module 在介绍ASP.NET Core Web实现之前,先来了解下ASP.NET Core Module.该模块是插入 IIS 管道的本机 IIS 模块(本机是指 ...

  7. 各大网站的WEB服务器分析

          今天研究一下HTTP协议,顺便分析了一下各大网站的WEB服务器,结果如下      分析的网站数量:194个,可能有重复的,其中比例     Apache:97,比例 59%     Mi ...

  8. 伪装nginx版本防止***web服务器

    为了防止被***扫描到web服务器信息,通过相对应的web服务器信息找出对应的版本漏洞,从而对web服务器进行***,nginx虽然功能强大,但是也是软件,软件就可能会有漏洞,例如nginx-0.6. ...

  9. 电商网站搭建——什么是Nginx?常见web服务器有哪些?

    一.什么是Nginx Nginx(engine x)是一个高性能的HTTP(请求-响应协议)和反向代理web服务器,同时也提供IMAP/POP3/SMTP服务.  --引用自百度百科 1.主要功能是反 ...

  10. linux搭建web服务器原理,【LINUX】linux搭建web服务器

    linux httpd 假设服务器地址为192.168.80.20/241.将准备安装的httpd软件包共享给everyone, (1)在linux上mount.cifs  //真机IP地址/共享文件 ...

最新文章

  1. R语言广义线性模型Logistic回归模型列线图分析(nomogram)
  2. html css右下角三角形,html – 框内的CSS中的三角形
  3. AM-资产冻结与停用
  4. Verilg 2001相对于Verilog 1995的改进(Z) (内含 乘方 运算符** )
  5. 信息学奥赛一本通 1095:数1的个数 | OpenJudge NOI 1.5 40
  6. 初创公司 经营_LibreCorps指导人道主义初创公司如何运行开源方式
  7. win2008r2 or centos6 硬盘挂载
  8. 归并排序——java
  9. 【AAAI2021】NLP所有方向论文列表(情感分析、句法、NER、对话/问答、关系抽取、KD等)...
  10. mui 与vue 混合开发的可行性分析
  11. 定义范围中的备选方案生成、横向思维、创建WBS、工作包定义、WBS、确认范围过程和实施质量过程的关系、联合应用设计和质量功能展开QFD...
  12. jenkins集成自动化配置(二) 创建项目和项目配置
  13. 如何下载jQuery
  14. 基于成本效益的深度信任网络的智能LEACH的多级动态优化附Matlab代码
  15. 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明
  16. Python | 人脸识别系统 — 用户操作
  17. pythonclass语法_【python类别概念自学】class的语法整理(继承、抽象类别、魔术方法)...
  18. xml格式化 java_Java XML格式化程序
  19. Android 语音识别+语音搜索源码 Voice Search
  20. GCN图卷积神经网络综述

热门文章

  1. html5 星际摩托,HTML5 星际陨石环绕动效
  2. juc-并发工具类源码解析
  3. DevOps工程师到底做些什么?
  4. IDC 监控技术介绍
  5. 华为不同vlan单臂路由的配置
  6. C语言 · 字符删除
  7. HDU 3729 I#39;m Telling the Truth(二部图最大匹配+结果输出)
  8. makefile编写---.c .cpp 混合编译makefile 模板
  9. 基于Krpano的Hotspot热区插件·第二版
  10. 分析网站速度和性能的最佳工具