Hi,各位客官大家好,我是老李。
今天这一节严格意义上其实不能算一个章节而应该是一个番外篇。因为通过前面翔实而又丰富的内容中,我认为大家已经具备了可以理解[ 同步、异步、阻塞、非阻塞 ]的条件了。这TM四个名词不仅每个单拎出来恶心人,而且TA们之间还会相互组合产生四个更让人恶心的名词:
我记得我在前面讲解socket、select系统调用等文章的时候,结合代码反复解释过[ 非阻塞 ]与[ 阻塞 ]概念,今天这篇番外我通过一个举例说明来再次说明下这几个词的含义。当然了,由于本人水平有限,也不一定准确合适,欢迎后台发消息提出质疑以及更正!所有表达一概将由下篇文章补充发出。
你们还记得买馒头的阿星和卖馒头的阿梅么?
我就用[ 买馒头 ]和[ 卖馒头 ]来举例说明下吧,但是作为举例,这些例子很有可能不太会符合生活日常现象。
当然了,由于买馒头的声称自己同时是一个研究僧(seng,一声),所以我考虑下面用研究僧来称呼他。
总结一下大概意思就是:
只是[ 同步 ]和[ 阻塞 ]傻傻分不清,是因为他们表现的最终结果太像了。
只是[ 异步 ]和[ 非阻塞 ]傻傻分不清,是因为他们表现的最终结果太像了。
然后我们继续用[ 买卖馒头 ]来说明组合后的词语:
咋样,这波儿连比划带解释,xue微能说清楚了点儿了么?然后我再摆一张关于IO的分类,其实在APUE里关于IO分为下面五大类:
注意:前四个都是同步IO,而只有最后一个是异步IO。也就是说select\poll\epoll也是同步的,而在Linux下只有AIO(PHP中的扩展叫做EIO)是异步。
真是见了鬼了,Nginx事件是基于epoll实现的,但是大家一直对TA的印象就是[ 异步非阻塞 ];Swoole事件也是基于epoll实现的,也称[ 异步非阻塞 ],结果到这里你跟我说[ IO复用 ]是同步?
是的
这件事情我需要从头到尾来给大家叨叨一下了,主要问题就是:我们站在什么样的角度和场景去聊的[ 同步 ]和[ 异步 ]。
场景一:你和前端在联调业务,前端跟你来了一句[ 我ajax异步把数据提交给你 ]。这里异步是说什么?是说产品联调上的数据转送流程,毫无疑问他一定不是再跟你探讨IO复用、AIO,对吧?
场景二:PHP API这块儿在用户支付完成后,在成功的回调里把订单信息[ 异步 ]放到消息队列。这里的异步在说什么?是在说业务流的逻辑流程。我坚信你们的PHP代码在把消息放入消息队列的时候用的函数方法都是同步且阻塞,不可能是异步,所以这里说异步不可能在是在说IO复用、AIO。
场景三:Nginx是基于事件监听的异步非阻塞高性能服务器,这里的异步是在说什么?既然在Linux下Nginx事件是基于epoll实现的,然而上面又说了epoll这样的IO复用属于同步,那这里为什么会说[ 异步 ]非阻塞?因为它形容的是Nginx整体的事件处理流程,而不单单是说对epoll的调用,明白了吧。或者可以这么理解,Nginx对请求的上层逻辑流程是异步的,底层的实现是同步的。
那么真正意义上的异步是什么?在Linux下,指的就是AIO,唯有AIO才是真正符合定义(此处定义既指APUE中的经典异步定义)的异步!但实际上截止到目前为止,由于老李见识比较短浅,至今未发现Linux平台下基于AIO做出的比较重量级的应用,而且数量比较少见,更多还是基于IO复用。
所以如果是你自己想研究异步非阻塞,你要搞清楚此处异步是指什么;和他人在工作中提到了异步,都要搞明白具体的场景和立场是什么,两个人在一个频道上才能扯明白。对方说ajax异步提交数据,你却理解为AIO,能说到一块儿?两个人中必须得有一个包容对方的理解范围才能聊明白咋回事,不然纯粹就是两个糊涂蛋在各自频道上激情发挥。
下个章节通过代码实战来说明下[ 同步阻塞 ]和[ 同步非阻塞 ],AIO的咱就不碰了,有兴趣同学自己可以折磨下自己。