Unix 网络 IO 模型: 同步异步, 傻傻分不清楚?

出处

阻塞 IO, 非阻塞 IO, 同步 IO, 异步 IO 这些术语相信有不少朋友都也不同程度的困惑吧? 我原来也是, 什么同步非阻塞 IO, 异步非阻塞 IO 的, 搞的头都大了. 后来仔细读了一遍
《UNIX 网络编程卷一 套接字联网 API(第三版)》的 6.2 章节, 终于把这些名词搞懂了.

下面我以《UNIX 网络编程卷一 套接字联网 API(第三版)》的 6.2 章节的内容为准, 整理了一下各种网络 IO 模型具体定义以及一些容易混淆的地方.

简介

Unix 下有 5 种可用的 IO 模型, 分别是:

  • 阻塞式 I/O
  • 非阻塞式 I/O
  • I/O 复用(select 和 poll)
  • 信号驱动式 I/O (SIGIO)
  • 异步 I/O (POSIX 的 aio_系列函数)

阻塞式 I/O 模型

最流行的 IO 操作是阻塞式 IO(Blocking IO). 以 UDP 数据报套接字为例, 下图是其阻塞 IO 的调用过程:

1462343854639.png

在上图中, 进程调用 recvfrom, 其系统调用直到数据报返回并且被复制到应用进程的缓冲区中 或者发送错误时才返回. 因此进程在调用 recvfrom 开始到它返回的整段时间内都是被阻塞的.

非阻塞式 IO(Non-Blocking IO)

进程把一个套接字设置为非阻塞是在通知内核: 当调用线程所请求的 IO 操作需要调用线程休眠来等待操作完成时, 此时不要将调用线程休眠, 而是返回一个错误.

非阻塞式 IO

如上图所示, 前三次调用 recvfrom 时, 没有数据可返回, 因此内核转而立即返回一个 EWOULDBLOCK 错误. 第四次调用 recvfrom 时, 已经有数据了, 此时, recvfrom 会阻塞住, 等待内核将数据赋值到应用进程的缓冲区中, 然后再返回.(注意, 当有数据时, recvfrom 是阻塞的, 它会等待内核将数据复制到应用进程的缓冲区后, 才返回).
当一个应用进程像这样对一个非阻塞描述符循环调用 recvfrom 时, 我们称之为轮询(polling). 应用进程持续轮询内核, 以查看某个操作是否完成, 这么做会消耗大量的 CPU 时间, 不过这种模型偶尔也会遇到, 通常是专门提供某一种功能的系统中才有.

IO 复用模型

有了 IO 复用(IO multiplexing), 我们就可以调用 select 或 poll, 阻塞在这两个系统调用中的某一个之上, 而不是阻塞在真正的 IO 系统调用上. 例如:

IO 复用模型

如上图所示, 当调用了 select 后, select 会阻塞住, 等待数据报套接字变为可读. 当 select 返回套接字可读这一条件时, 我们就可以调用 recvfrom 把所读取的数据报复制到应用进程缓冲区.
对比阻塞式 IO, IO 复用模型优势并不明显, 并且从使用方式来说, IO 复用模型还需要多调用一次 select, 因此从易用性上来说, 比阻塞式 IO 还略有不足. 不过 select 的杀手锏在于它可以监听多个文件描述符, 大大减小了阻塞线程的个数.

信号驱动 IO 模型

信号驱动 IO 模型

信号驱动模型如上图所示. 当文件描述符就绪时, 我们可以让内核以信号的方式通知我们.
我们首先需要开启套接字的信号驱动式 IO 功能, 并通过 sigaction 系统调用安装一个信号处理函数. sigaction 系统调用是异步的, 它会立即返回. 当有数据时, 内核会给此进程发送一个 SIGIO 信号, 进而我们的信号处理函数就会被执行, 我们就可以在这个函数中调用 recvfrom 读取数据.

异步 IO 模型

异步 IO (asynchronous IO) 由 POSIX 规范定义, 在 POSIX 中定义了若干个异步 IO 的操作函数. 这个函数的工作原理是: 告知内核启动某个动作, 并让内核在整个操作(包括将数据从内核复制到应用进程缓冲区)完成后通知我们的应用进程.
异步 IO 模型和信号驱动的 IO 模型的主要区别在于: 信号驱动 IO 是由内核通知我们何时可以启动一个 IO 操作, 而异步 IO 模型是由内核通知我们 IO 操作何时完成.
异步 IO 模型的操作过程如图所示:

异步 IO 模型

当我们调用 aio_read 函数时(POSIX 异步 IO 函数以 aio_或 lio_ 开头), 给内核传递描述符, 缓冲区指针, 缓冲区大小(和 read 相同的三个参数) 和文件偏移(以 lseek 类似), 并告诉内核当整个操作完成时如何通知应用进程. 该系统调用立即返回, 而且在等待 IO 完成期间, 应用进程不被阻塞.

各种 IO 模型的比较

各种 IO 模型的比较

如图所示, 上述五中 IO 模型中, 前四种模型(阻塞 IO, 非阻塞 IO, IO 复用, 信号驱动 IO)的主要区别在于第一阶段, 因为他们的第二阶段是一样的: 在数据从内核复制到调用者的缓冲区期间, 进程阻塞于 recvfrom 调用. 而第五种, 即异步 IO 模型中, 两个阶段都不需要应用进程处理, 内核为我们处理好了数据的等待和数据的复制过程.

关于同步 IO 和异步 IO

根据 POSIX 定义:

  • A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes(导致请求进程阻塞, 直到 IO 操作完成).
  • An asynchronous I/O operation does not cause the requesting process to be blocked(不导致请求进程阻塞).
    根据上述定义, 我们的前四种模型: 阻塞 IO 模型, 非阻塞 IO 模型, IO 复用模型和信号驱动 IO 模型都是同步 IO 模型, 因为其中真正的 IO 操作(recvfrom 调用) 会阻塞进程(因为当有数据时, recvfrom 会阻塞等待内核将数据从内核空间复制到应用进程空间, 当赋值完成后, recvfrom 才返回.) 只有异步 IO 模型与 POSIX 定义的异步 IO 相匹配.

总结

在处理网络 IO 操作时, 阻塞和非阻塞 IO 都是同步 IO.
只有调用了特殊的 API 才是异步 IO.

同步/异步 IO

因此网上常说的 "同步阻塞 IO", "同步非阻塞 IO" 其实就是阻塞 IO 模型和非阻塞 IO 模型, 因为阻塞 IO 和非阻塞 IO 模型都是同步的, 加了 "同步" 二字其实是多余了.
网络上常说的 "异步非阻塞 IO" 其实就是异步 IO 模型.

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

推荐阅读更多精彩内容