浅谈I/O模型

一:概念的理解: 

首先在网络编程的时候,我们常常见到同步/异步,阻塞/非阻塞四中调用方式:

1同步和异步主要针对C(client)端 

同步: 

所谓的同步,就是在c端发出一个功能调用时,在没有得到结果之前,该调用步返回,也就是说必须一件一件事做,等前一件事完了之后才做后一件事。 

如:普通的B/S模式(同步):提交请求->等待服务器处理->处理完毕返回,这期间客户端浏览器不能干任何事

异步: 

与同步相对。当C端一个异步过程调用发出之后,调用者不能立即得到结果,实际处理这个调用的部件在完成后,通过状态,通知和回调来通知调用者。 

如:请求通过事件触发->服务器处理(浏览器仍然可以做其他事情)->处理完毕

阻塞和非阻塞主要针对S端(server)

阻塞 

阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态,cpu不会分配时间片,线程暂停运行)函数只有得到结果返回。 

阻塞调用和同步调用的区别:对同步来说,很多时候当前线程还是激活的,只是逻辑上没有返回,如,在socket编程中调用recv函数,如果缓冲区没有数据,这个函数就会一直等待,直到有数据返回。而此前当前线程还有可能继续处理各种各样的消息。

阻塞的例子:比如去取A楼一层(假设是内核缓冲区)取快递,但是比不知道什么时候来,你有不能干别的事情,只能死等着但是可以睡觉(进程处于休眠状态),因为你知道快递把货送来时一定会给比大电话

非阻塞: 

非阻塞与阻塞概念想对应,指在不能立即得到结果之前,该函数不会阻塞当前线程,而会立即返回。

非阻塞的例子:还是等快递,如果用轮询的方式,每隔5分钟去A楼一层(内核缓冲区)去看快递来了没,没来,立即返回,如果快递来了,就放到A楼一层,等你去取。

对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但不是一一对应的。阻塞对象上可以有非阻塞的调用方式,我们可以通过轮询状态,在适当的时候调用阻塞函数,就可以避免阻塞,而对于非阻塞对象,调用函数可以进入阻塞调用,对于select: 

1:同步 

我客户端(C端调用者)一个功能,该功能没有结束前,我死等结果。 

2:异步,我(c端调用者)调用一个功能,不知道该功能结果,该功能有结果后通知我,即回调通知

同步和异步主要针对c端,但是跟s端不是完全没关系,同步和异步必须s端配合才能实现,同步和异步由c端控制,但是s端是否为阻塞还是非阻塞,c端不关心。

3:阻塞,就是调用我(s端被调用者,函数),我(s端被调用者,函数)没有完全接受完数据或者没有得到结果之前,我不会返回。

4:非阻塞,就是调用我(s端被调用者,函数),我(s端被调用者,函数)立即返回,通过select通知调用者

二:同步I/O和异步I/O 

同步I/O与异步I/O的区别在与数据访问的时候进程是否阻塞 

阻塞I/O与非阻塞I/O的区别在与:应该程序的调用是否立即返回。

阻塞和非阻塞是指server端的进程访问的数据如果尚未就绪,进程是否需要等待,简单说这相当于函数内部的实现区别,也就是未就绪时时直接返回还是等待就绪。

就同步和异步是指client端访问数据的机制,同步一般指主动请求并等待I/O操作完毕的方式,当数据就绪后再读写额时候必须阻塞,异步则指主动请求数据后便可以继续处理其他任务,随后等待I/O,操作完毕的通知。

三:五种I/O模型: 

1)阻塞I/O 

2)非阻塞I/O 

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

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

5)异步I/O 

前四中是同步,最后一种是异步。 

阻塞I/O模型: 

简介:进程会一直阻塞,直到数据拷贝完成 

应用程序调用一个I/O函数,导致应用程序阻塞,等待数据准备好,如果数据没有准备好,一直等待。。数据准备好,从内核拷贝到用户空间,I/O函数返回成功

阻塞I/O模型图:在调用recv()/recvfrom()函数,发生在内核中等待数据和复制数据过程。 


当调用recv()函数时,系统首先检查是否有准备好的数据,如果数据没有准备好,那么系统就处于等待状态,当数据准备好后,将数据从系统缓冲区复制到用户空间,然后函数返回。在套接应用程序中,当调用recv()函数时,未必用户空间就已经存在数据,那么此时recv()函数处于等待状态 

非阻塞I/O模型: 

简介:我们把一个套接口设置为非阻塞就是告诉内存,当所请求的I/O操作无法完成时,不要进程睡眠,而是返回一个错误,I/O函数会不断的测试数据是否准备好,没有准备好,继续测试,直到数据准备好为止。在测试的过程中会占用大量的CPU时间。 


I/O多路复用模型: 

简介:主要是select和epoll;对于一个I/O端口,两次调用,两次返回,比阻塞I/O并没有什么优势,只是能实现同时对多个I/O端口进行监听。

I/O多路复用模型会调用select,poll函数,这几个函数也会使进程阻塞,但是和阻塞I/O不同的,这个函数可以同时阻塞多个I/O操作,而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。 


IO多路复用适用场合:

当客户端处理多个描述符时(请求)(一般是交互式输入和网络套接口),必须使用I/O复用

当一个客户端同时处理多个套接字时,此情况可能的但很少出现

当一个TCP服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用 (使用最多的场景)

当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用

当一个服务器要处理多个服务或多个协议,一般要使用I/O复用


信号驱动I/O 

简介:两次调用,两次返回 

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


异步I/O模型: 

简介:数据拷贝的时候进程无需阻塞 

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


四:五种I/O模型的比较


五:I/O模型的具体实现

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

Select:Linux实现对应,I/O复用模型,BSD4.2最早实现

Poll:Linux实现,对应I/O复用模型,System V unix最早实现  (改进版的select)

Epoll:Linux实现,对应I/O复用模型,具有信号驱动I/O模型的某些特性

Kqueue:FreeBSD实现,对应I/O复用模型,具有信号驱动I/O模型某些特性

/dev/poll:SUN的Solaris实现,对应I/O复用模型,具有信号驱动I/O模型的某些特性

Iocp  Windows实现,对应第5种(异步I/O)模型


六:select/poll/epoll的比较:


1,select

优点

Select:POSIX所规定,目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理 

缺点

单个进程可监视的fd数量被限制,即能监听端口的数量有限  cat /proc/sys/fs/file-max 

对socket是线性扫描,即采用轮询的方法,效率较低 

select 采取了内存拷贝方法来实现内核将 FD 消息通知给用户空间,这样一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大 

2, poll

本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态

其没有最大连接数的限制,原因是它是基于链表来存储的

大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义

poll特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd  (通知多次)

边缘触发:只通知一次,性能更好

3,epoll

在Linux 2.6内核中提出的select和poll的增强版本

优点:

支持水平触发LT和边缘触发ET,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次

使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知

没有最大并发连接的限制:能打开的FD的上限远大于1024(1G的内存能监听约10万个端口)

效率提升:非轮询的方式,不会随着FD数目的增加而效率下降;只有活跃可用的FD才会调用callback函数,即epoll最大的优点就在于它只管理“活跃”的连接,而跟连接总数无关

内存拷贝,利用mmap(Memory Mapping,内存映射)加速与内核空间的消息传递;即epoll使用mmap减少复制开销

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

推荐阅读更多精彩内容