五种 IO 模型

五种 IO 模型

参考链接

一共有五种 IO 模型

  • 阻塞 IO
  • 非阻塞 IO
  • 多路复用 IO
  • 信号驱动 IO
  • 异步 IO
    其中,前面4种是同步IO,最后一个是异步IO

IO 简述

IO 模型.jpg

IO (Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作,通常用户进程中的一个完整IO分为两阶段:用户进程空间<-->内核空间、内核空间<-->设备空间(磁盘、网络等)。IO有内存IO、网络IO和磁盘IO三种,通常我们说的IO指的是后两者。

LINUX中进程无法直接操作I/O设备,其必须通过系统调用请求kernel来协助完成I/O动作;内核会为每个I/O设备维护一个缓冲区。

对于一个输入(读取到内存)操作来说,进程IO系统调用后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备中读取,因为设备IO一般速度较慢,需要等待;内核缓冲区有数据则直接复制到进程空间。

所以,对于一个网络输入(读取网络资源)的操作,通常包括两个部分

  • 等待网络数据到达网卡 --> 读取到内核空间 (这个过程就是准备数据)
  • 从内核缓冲区复制数据到进程空间
  • 然后具体的用户函数,把结果返回。
    IO 操作发生时一般涉及两个对象,一个是调用这个IO的 process (or thread) ,另一个就是系统内核 (kernel)。

IO 模型介绍

我们在介绍IO模型的时候,是根据IO操作的两个阶段,是否被锁了来分类的。
下面我们使用获取一个网络资源来举例(读取数据),假设是 read 方法。

阻塞 IO

  • 准备数据阶段(用户进程阻塞)
  • 复制数据阶段(用户进程阻塞)

当用户进程在读取一个网络资源的时候,内核就开始了IO的第一个阶段:准备数据。

对于网络IO来说,数据一开始还没有准备好(比如还没有收到完整的UDP包),这个时候内核就要等待足够数据到来。

当数据没有准备好,在用户进程这边,用户的进程就会被阻塞,一直等待数据准备好。

当数据准备好了(数据在内核空间中),然后就需要把数据复制到用户进程空间,在复制数据的这个过程中,用户进程仍然是阻塞的。

总结:阻塞IO,就是指当调用读取数据的函数(比如 read),这个函数不立马返回结果,而是阻塞当前进程,直到数据被复制到用户进程空间或者是超时出错才解除阻塞,并返回结果。

缺点:实际上,除非特别指定,几乎所有的IO接口 ( 包括socket接口 ) 都是阻塞型的。这给网络编程带来了一个很大的问题,如在调用 recv(1024) 的同时,线程将被阻塞,在此期间,线程将无法执行任何运算或响应任何的网络请求。

一个简单的解决方案

使用多线程或者多进程,多线程(或多进程)的目的是让每个连接都拥有独立的线程(或进程),这样任何一个连接的阻塞都不会影响其他的连接。或者是使用线程池,进程池。

非阻塞 IO

  • 准备数据阶段(用户进程非阻塞)
  • 复制数据阶段(用户进程阻塞)

如果采用非阻塞的方式读取数据,当用户调用 read 方法的时候。

如果数据还没有准备好,内核就立马返回一个结果给用户进程(error),用户进程不会阻塞,用户知道数据还没有准备好,那么就可以过一段时间再调用 read 方法进行获取数据,而且在两次 read 的时间间隔中,用户进程还可以做其他操作。

一旦数据准备好了(在内核空间中),而且恰好用户调用了 read 方法,那么数据就会被复制到用户进程空间并返回给用户,复制到用户进程空间这个过程也是阻塞的。

总结:在非阻塞 IO 中,用户在调用 read 方法后,进程没有被阻塞。内核会立马返回数据给进程,这个数据可能是error提示,也可能是最终的结果。如果要得到最终的结果,就需要用户进程主动的多次调用 read 方法。

重复调用 read 方法的过程,称为轮询。轮询检查内核数据,直到数据准备好,再拷贝数据到进程,进行数据处理。需要注意,==拷贝数据整个过程,进程仍然是属于阻塞的状态==。

缺点:轮询调用 read 是很费CPU资源的,所以一般我们会在代码中加入 time.sleep(2)。但是加入了 sleep 以后,任务的执行时间长了,因为我们不确定,任务多久执行完成。

多路复用 IO

暂时不考虑

信号驱动 IO

当调用 read 函数的时候,准备数据的过程中用户线程不阻塞,用户线程可以去做其他事情。等到数据准备完了,用户进程会收到一个SIGIO信号,然后可以在信号处理函数中处理数据。

复制数据的阶段,仍然是阻塞的。

异步 IO

相对于同步IO,异步IO不是顺序执行的。用户调用 read 之后,准备数据阶段和复制数据阶段,都是非阻塞的。

数据准备好了后,内核直接复制数据给用户进程空间,然后从内核向进程发送通知,然后用户进程处理数据。

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

推荐阅读更多精彩内容