I-O 模型如何演进及 I-O 多路复用是什么?

什么是IO

I/O 是 Input/Ouput的缩写,即输入输出端口,是信息处理系统(例如计算机)与外部世界(可能是人类或另一信息处理系统)之间的通信。输入是系统接收的信号或数据,输出则是从其发送的信号或数据。

I/O 先修知识

I/O 也是一个很宽泛的词,每个设备都会有一个专用的 I/O 地址,用来处理自己的输入输出信息。对于服务端研发的童鞋相信 网络 I/O、磁盘 I/O 这些词,也需并不陌生,一次 API 接口调用、向磁盘写入日志信息,其实就是在跟 I/O打交道。一次 I/O操作分为等待资源、使用资源两个阶段,以下分别进行介绍。

阻塞与非阻塞 I/O

阻塞与非阻塞 I/O是对于操作系统内核而言的,发生在等待资源阶段,根据发起 I/O 请求是否阻塞来判断。

==阻塞 I/O==:这种模式下一个用户进程在发起一个 I/O 操作之后,只有收到响应或者超时才可进行处理其它事情,否则 I/O 将会一直阻塞。以读取磁盘上的一段文件为例,系统内核在完成磁盘寻道、读取数据、复制数据到内存中之后,这个调用才算完成。阻塞的这段时间对 CPU 资源是浪费的。

==非阻塞 I/O==:这种模式下一个用户进程发起一个 I/O 操作之后,如果数据没有就绪,会立刻返回(标志数据资源不可用),此时 CPU 时间片可以用来做一些其它事情。

同步与异步 I/O

同步与异步 I/O 发生在使用资源阶段,根据实际 I/O 操作来判断。

==同步 I/O==:应用发送或接收数据后,如果不返回,继续等待(此处发生阻塞),直到数据成功或失败返回。

==异步 I/O==:应用发送或接收数据后立刻返回,数据写入 OS 缓存,由 OS 完成数据发送或接收,并返回成功或失败的信息给应用。Node.js 就是典型的异步编程例子。

用户空间与内核空间

操作系统为了支持多个应用同时运行,需要保证不同进程间相对独立、内核的安全,那就不能谁都能来操作了,因此操作系统将内存空间划分为用户空间、内核空间两部分。用户空间存放用户程序代码和数据,而内核空间存放内核代码和数据。

其实一直以来对于用户空间与内核空间的界限划分还是有点傻傻分不清的感觉,最近读到了一篇文章 解读I/O多路复用技术 //www.greatytc.com/p/db5da880154a,上面有段描述,分别从 OSI 七层模型图 和 网际网协议族 来看待用户空间与内核空间的分界线,此处引用下图片,总结性的说明下,更详细的推荐去作者网站看下原文讲解。

OSI 七层模型与网际网协议族图

可以看到这里以传输层做了边界划分,传输层之上为用户空间(Web 客户端、浏览器、FTP 这些都属于上三层),下四层为内核空间,例如传输层的 TCP、UDP 协议就对应到了内核空间。


1.png

操作系统 I/O 模型演进

操作系统的 I/O 模型分为:阻塞 I/O、非阻塞 I/O、I/O 复用、信号驱动 I/O、异步 I/O 五种,本节参考 Unix 网络编程一书,图片也引自本书中,以下分别进行介绍。

同步阻塞 IO

从应用程序开始系统调用->数据就绪进行拷贝->拷贝结束,这之间应用程序都处于等待状态,不能做其它事情,直到将数据拷贝到用户空间或出错才返回,我们称之为阻塞 I/O 模式。

2.png

同步非阻塞 IO

相比于同步阻塞 I/O 模式,同步非阻塞 I/O 在每次调用之后,如果数据没有就绪就会立即返回,之后重复调用来检查 I/O 操作是否就绪,这对 CPU 资源是一个极其浪费的操作,直到数据就绪将数据从内核拷贝到用户空间,返回成功指示给到应用程序。

Read:就是一种实现,通过重复轮询 I/O 来判断。


3.png

IO 多路复用

链接(Socket)并发大的情况,上面两种就不适合了,前面一个处理不完,后面就只能干等,这里就用到了 I/O 多路复用技术,下图所示相比较前两种,分为了两步,先进行 select 数据就绪后,在调用 recvfrom 进行真正的 I/O 读写操作。它的高级之处还在于能够一个线程同时处理多个 Socket。

4.png

什么是 I/O 多路复用?

【面试指南】请解释下什么是 I/O 多路复用?

有必要先弄清这个概念,这里的 I/O 通常指网络 I/O,多路指多个 Socket 链接,复用指操作系统进行运算调度的最小单位线程。整体意思也就是多个网络 I/O 复用一个或少量的线程来处理 Socket。关于 I/O 多路复用的多种实现,继续参考下文。

I/O 多路复用的四种实现

I/O 多路服用有多种实现模式:select、 poll、 epoll、 kqueue

  • select

通过轮询检查在文件描述符上设置的标识位来进行判断,select 的轮询相当于在数据库中查找一条记录没有建立索引,对所有的 socket 进行全部遍历,这对 CPU 是浪费的。另外 select 还有一个限制,对于单个进程所能打开的文件描述符最大只能是 1024,那么基于 select 的轮询技术最多也只能很好的处理 1000 并发的吞吐量,可以查看 上一个10年,著名的C10K并发连接问题

  • poll

poll 和 select 在实现上没有本质的区别,相比较 select,poll 基于链表来实现,没有了最大链接 1024 的限制。但是当文件描述符多了之后,每次调用都会对链接进行线性遍历,性能还是十分低下的。

  • epoll

是 linux 下效率最高的 I/O 事件通知机制,没有最大链接限制,通过 callbak 回调通知机制,不在是每次调用都对链接进行线性遍历,这样就不会随着文件描述符的增加导致效率下降。

在 1GB 内存的机器上能监听大约 10 万个端口,远超过 select 的 1024 限制,具体可以在服务器上查看 cat/proc/sys/fs/file-max

  • kqueue

与 epoll 类似,仅存于 FreeBSD(一种类UNIX操作系统)。

信号驱动 IO

仅在 Unix 上支持,与 I/O 多路复用相比避免了 select 的阻塞轮询。应用程序进行系统调用后立即返回,处理其它事物,在数据就绪之后系统会发送一个 SIGIO 信号到应用程序,应用进程开始读取数据。


5.png

异步 IO 模型

异步 I/O 模型是目前最理想的一种形式,应用程序发起系统调用后无需等待直接返回当前调用状态,进行后续的其它任务,结果由内核完成 I/O 操作之后通过回调通知到我们的应用程序,中间没有阻塞过程。

在 Linux2.6 之后增加了异步 I/O 的实现方式 AIO,但是很少系统能够实现。


6.png

白话风格讲解 I/O 模型的演进

上面讲解了几种 I/O 模型的演进,如果不明白的,我们通过白话风格(小明与妹子的邂逅)讲解操作系统 I/O 模型是什么?之间的区别是什么?

故事标题:小明与妹子的邂逅

故事情节:小明在校园一次文艺晚会上邂逅了一位妹子,在只得知妹子名字、手机号的情况下,经过几天的苦苦追寻,历经千山万水,终得美人归!
演员介绍:男一号@小明、女一号@妹子、串场@门卫大爷

  • 同步阻塞 I/O 模式

小明电话相约妹子在校门口,然后小明很专一、不见到妹子不回家,期间没有做任何事情,一直在等待!

  • 同步非阻塞 I/O 模式

小明电话相约妹子在校门口,妹子还没准备好(出门前化妆几小时。。。),这时候的小明很执着,每隔一会儿给妹子发个信息直到妹子准备好了。

  • I/O 多路复用模式

select 小明电话相约妹子在校门口,委托门卫select大爷帮忙,select大爷很敬业每出去一个人都会进行询问,但是select大爷有个限制最多只能询问1024个。

poll poll类似于select功能,不同的是poll大爷没有1024限制,可以一直坚持,但是当poll大爷超过1024,询问的越来越多之后就显得越来越精疲力尽了。

epoll 小明电话相约妹子在校门口,委托门卫epoll大爷帮忙,epoll大爷不在是每个询问,规定每个人出入校门必须带上学生证,这样opoll大爷就是知道哪个是小明的女神了,epoll大爷找到女神之后在电话通知小明。

  • 信号驱动 I/O 模式

小明电话相约妹子在校门口,此时妹子回复说我还没准备好(出门前化妆几小时。。。),这个时候小明也没去,而是先去干其它事情了,等妹子准备好之后电话通知小明,我已经准备好了,小明这个时候才去校门口等着和妹子的约会。

  • 异步 I/O 模式

小明告诉妹子我们在校园门口相约,之后小明没有在那干等了,而是先回宿舍休息会或者和朋友在打会球等等,妹子到校门口之后电话通知小明,我已经来啦。

Select VS Epoll

【面试指南】如果问到轮询技术的实现一般也会考察 select 和 epoll 的区别?

转自公众号NodeJs技术栈

在操作方式上区别

  • select 采用了线性遍历来查找,链接多了之后可以想象一下在一个诺大的数组中每次通过遍历来锁定一个链接,是多么的消耗性能。

  • epoll 则不需要遍历,采用的是回调机制,可以看作一个 HashTable,来锁定一个对象是很快的。

文件描述符限制

  • 对于文件描述符(最大连接数)select 限制为 1024。
  • epoll 则没有这个限制,通常在 1G 内存的机器上所能支持的连接数为 10W 左右。

对于操作系统的支持

从操作系统支持上来看,目前流行的高性能 Web 服务器 Nginx 是基于 epoll来实现高并发,当然如果你的链接很小的情况下区别还是不大的 select也能满足,如果是大流量、高并发情况 epoll 目前还是首选模型。

转自Nodejs技术栈公众号

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容