同步?异步?

文章引自:http://justing.me/article/20160425111950

                                                                   异步编程之我所见

记得2年前的一次面试中面试官问我什么是“异步(编程)”,当时我不确定自己是不是对这个概念有没有准确的理解,我就给他打了个比方:假如你要烧一壶水,你不可能一直在旁边等着水开,你肯定得在水开之前去干别的事情,等水开了之后你再回头继续处理它(比如把它灌进热水瓶)。记得当时面试官对我的这个解释很满意。直到现在我也还是不确定到底对这个概念有没有更深的理解,至少现在再拿这个比喻说事情还是很合适的。

说到“异步”,那必须要说的就是“同步”,所谓同步就是一直在旁边等水开了呗。我有一段时间一直简单的以为以异步的方式处理事情在速度上肯定会比同步的方式快,但是如果仔细想,这样理解并不准确。就拿烧水这件事本身来说,无论在同步还是异步的情况下,水从常温到烧开再到它进入热水瓶的这段时间几乎是一样的,可能在异步的情况下还不如同步呢(因为水开的时候你有可能正在处理其他的事情要耽搁下,而如果你是一直守在旁边就不一样了,自然这个时间相对烧水这件事本身来说可以忽略不计)。那既然这样,异步的优势在哪?再拿这个例子来说,如果你是一直守着等水开(同步),就在这时你老妈突然又叫你去门口小店买瓶酱油,你说:我在等水烧开呐~。然后你老妈不得不叫你妹妹或者弟弟去买。而如果你不是那么傻(异步),那就同时可以替你妈去买酱油,回来指不定水刚好开了。我们不是傻子,肯定不会这么干,否则就太浪费劳动力了,对于计算机来说就是资源利用率太低了(CPU)。所以异步的好处往往并不是提高做一件事情的速度,而是提高做很多事情的整体效率。

说到异步很多人都会想到多线程,觉得没有多线程肯定就没法异步了。异步是否一定需要多线程?我觉得两者没有必然的联系,你仍然可以在一个线程的情况下完成异步操作,就像你一个人仍然可以在烧水的时候干很多其他事情。典型地拿Node来说,它不就是只有一个线程么。我们不妨拿Node处理Http请求的例子来做一个简单的计算,比如有一个Http请求的流程是这样的:

请求到达Node,Node解析请求(请求到达Node前的网络传输时间不计算在内,因为网络的好坏不影响Node处理请求的速度);(1s)

Node发出数据库查询请求(IO操作);(98s)

Node得到数据库查询结果将其发送给客户端(假设这个结果很短,从数据库读取值的时间忽略不计,当然发送响应网络传输时间也不计在内);(1s)

我在上面的三个步骤中分别标记了处理时间,这个请求的时间消耗主要是在发出数据库查询请求到得到结果的这段时间(IO等待),需要98秒,其他两步只需要1秒时间,因为只是简单cpu计算,不需要IO操作。这样数量级的差距是很平常的。那么对于一个客户端来说,从请求到达Node到得到Node发回响应至少需要100s(中间减去了客户端和Node之间的网络传输时间)。现在有100个这样的请求先后到达了Node(假设是每秒1个),我们先假设Node是以同步方式处理这些请求,也就是说,Node在发出数据库查询请求之后一直等在那边什么事也不干。那么完成这100个请求需要100*100=10000s,对于客户端来说,排的越后的请求响应时间越长,最长的需要100*100 - 100=9900s,平均下每个客户端的响应时间是(9900+100)/ 2=5000s简直不能忍。但是Node采用的是异步IO,也就是说,在等待数据库查询结果返回之前它并不是啥事也不干干等在那边,在发出第1个数据库请求之后,继续发第2个,第3个......,经过在100s后发送完所有这100数据库查询请求,完了之后,在理想情况下这时Node的事件队列中已经有最早的那2个请求的数据库查询结果返回了,此时Node继续处理后续的数据库返回的结果,将其发送给客户端。现在来算一下每个客户端的响应时间:1s(Node解析请求时间)+ 98s(数据库查询时间)+ 1s(返回结果时间)+2s(在数据库返回结果队列中等待的时间)=102s,几乎和只有1个请求的时候一样!拿这个例子其实是要说明2点:

异步和多线程没有直接关系;

异步的好处是提高系统的伸缩性,响应性,资源利用率(上面的例子Node的CPU几乎的全负荷运行的,看看自己的电脑吧,CPU 90%的时间都躺在那啥事也不干!);

某些情况下我甚至可以得出这样的结论:

异步的目的就是要提高cpu的利用率,不要让它闲着!这个结论一般适用于IO限制的操作中(需要长时间IO等待),在计算限制的操作中(CPU要进行一个长时间的计算),比如在GUI程序中,我要通过一个关键字在选定的目录中查找所有出现过该关键字的文件以及出现的次数,这个操作可能会因为文件数量过多耗时很久,所以这个计算操作不能在主线程中进行,必须另外创建另外的线程去执行,在将来计算完成后告诉主线程计算结果。所以一般在计算限制的操作中,异步操作才需要涉及到多线程,对于主线程来说,操作是以异步方式进行的。当然这个时候cpu的利用率也就说不上是什么好处了,在计算限制的操作中,异步主要是防止主线程卡死。虽然这里用到了多线程技术,但是这里的多线程只是为了能够让主线程以异步的方式处理事情,和异步本身并没有太大关系。还有关于多线程的使用就是让多个线程同时处理一个事情,提高处理速度,比如当前的例子中子线程可以又开启多个线程并行地查找关键字,然而这又是另一码事,和异步一点关系都没有。

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

推荐阅读更多精彩内容