同步IO/异步IO, 阻塞IO/非阻塞IO

前提知识:用户态与内核态

开篇,我觉得应该先给这四个画一个等级。
同步IO和异步IO是更高层次的一个划分,阻塞IO/非阻塞IO同属于同步IO类别下,但是是不同的小类别。

1.同步IO(synchronous IO)
我以前有个误解:同步IO就代表着用户进程会在IO时等待,这个理解对了一半错了一半。看完下面就能豁然开朗了。
同步IO分为以下4种
1.1 阻塞IO (blocking IO)
用户进程在要访问网卡的时候,由于用户态没有这个权限,是需要调用系统函数recvfrom从用户态切换到内核态,
由于内核也需要从网卡上读取数据,所以在数据还没有准备好的时候,用户的进程就被阻塞这。内核读完了网卡数据,然后需要从内核空间再拷贝到用户内存空间。此时用户进程算是得到了数据,不再被阻塞,从而继续运行。
1.2 非阻塞IO (nonblocking IO)
用户调用recvfrom想要读数据,并设置参数flag为非阻塞的。此时发现内核态并没有准备好数据呢,好,那内核就告诉进程,数据还没有搞定,立即返回,那用户进程发现没有数据呢,那就先去干别的事情;过一会用户进程又来问内核要数据,此时内核已经准备好数据了,那内核负责将内核空间的数据拷贝到用户空间,然后函数返回,此时回到用户态。注意,这里其实依然是有个同步(或者叫短暂的阻塞),就是进程需要等待内核把数据从内核空间拷贝到用户空间。
1.3 多路复用IO (IO multiplexing)
select/poll/epoll 听过吧,其实就是用一个文件句柄来handle很多个socket,如果这个socket已经准备好数据了,那就用调用recvfrom来取数据。这个层次能相当于一个封装。 调用select/poll的时候,会去轮询所有在监听的file descriptor(文件描述符),如果说这个fd对应的数据ok了,放进fd_set里,最后返回这些fd,把他们从内核空间拷贝到用户空间,然后用户进程就拿到了这些fd,针对每个fd,用户进程需要调用recvfrom去把网络数据从内核空间拷贝到用户空间来。这里和阻塞IO/非阻塞IO有点不同,因为这些fd是已经确定数据ready了,所以比阻塞IO阻塞时间短,又不会像非阻塞IO那样可能数据没有准备好。epoll更高效一些,下一篇文章再详解epoll。特别注意,这里仍然是同步的概念,因为仍然需要把网络数据从内核里考到用户态里。
1.4 信号驱动IO (signal driven IO)
了解点宏观原理,再细节点不懂。原理就是用sigaction注册fd的处理函数,一旦这个fd数据ready了,通知对应的处理进程,这个进程再把数据从内核里拷贝出来。同上,有这个拷贝的过程,所以依然数据同步IO。

2.异步IO (asynchronous IO)
ok,终于到异步IO了。用户进程调用aio_read,告诉内核等数据准备好,并且复制到用户进程空间后执行事先指定好的函数,并且这个read会立即返回。当数据已经完成并复制到了用户空间,就会产生一个信号或执行一个基于线程的回调函数来完成这次 I/O 处理过程。

3.总结一下
异步和同步的差异:其实关键点就在与用户进程是否在等待把数据从内核空间拷贝到用户空间。所以阻塞不阻塞和同步没有啥关系。只要用户进程需要等待拷贝,那就是同步。
阻塞和非阻塞差异:阻塞和非阻塞都有短时间的等待拷贝过程,但是非阻塞IO会在没有数据的情况下不傻等。

4.更形象的例子
举个栗子,好理解又好记忆。
你是个人,对,叫A,你需要接电话,电话里的人B会告诉你一个串数字,你要给记下来,之后有用。
你就是用户进程,电话就是函数,电话里的人是内核进程。
(1.1)阻塞IO:你打电话给对方,要数字,因为B也没有那个数字呢,所以你就举着电话不放下,拼命等,等了半个小时后,B有数字了,告诉你,你给数字写到纸条上,挂电话。好的拿数字任务完成。
(1.2)非阻塞IO:你9点打电话给B,要数字,B说没有,好你挂了电话,去打球了。10点你又打,还没有,你又出去了。11点你再打电话,诶B告诉你有了,于是你记下来,挂电话。任务搞定。
(1.3)多路复用IO:你找了个新工作,现在变成了接线员,这有10个电话,每个电话你每隔一小时都打一下,问问对面有没有新的数字呢,对面如果说有,你把这个电话编号记下来。都打完了,把这些有新的数字的电话编号给你的客户们,然后告诉他们,你们可以打电话去要数字了,然后你的那些拿到号码的客户,去对应的电话打电话要数字,他们再把自己要的数字写在小纸条上。
(1.4)信号驱动IO: 你又不再是接线员了,做回个需要数字的人。你打电话告诉B,你那边数字搞定了打电话给我。然后出去喝酒了。B那边数据准备好了,打电话给你,你接电话,并把数字记录到小纸条上,然后挂电话。任务搞定。
(2)异步IO: 你变成老板了,牛逼炸了,打电话告诉B,你那边一旦拿到数字,你把数字写下来,把那个纸条给我亲自送过来,所以我就不用自己花时间来写纸条了,将来就直接用就可以了。

一些参考的博客:
信号驱动IO
https://blog.csdn.net/historyasamirror/article/details/5778378
https://www.cnblogs.com/langzibin/p/7755783.html

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

推荐阅读更多精彩内容