linux 下同步异步,阻塞非阻塞的一些想法

同步异步 阻塞非阻塞

今天和小伙伴讨论了这个问题,网上的说法有很多种,我按照自己的思路总结一边。
一句话总结区别:
同步异步关注的是事件发生时你的行为。
阻塞非阻塞关注的是的等待事件的状态。
下面看具体的分析

同步异步

同步:
在事件发生前,你的状态是时刻关注此事件,等待此事件给你返回结果。
例子:
烧水,同步就是你时刻关注着它,一段时间后,烧水壶冒烟了,你看见了,你知道水已经烧好。
那么在这段时间内你需要一直看着它是否冒烟。

异步:
在事件发生前,你并不关心此事件,而是自己去忙自己的,事件完成会通知你。
例子:
水烧好时,烧水壶会发出鸣声,你听见了,说明水烧好了
那么在这段时间内你不需要一直看着它,听见声音说明水已烧好。声音就是通知机制。

阻塞非阻塞

阻塞:
阻塞是你等待事件时为挂起状态,此时你什么也不能干,只能在等待事件。
例子:
烧水时,你在烧水壶旁边仅仅等待水开,水开了自己立刻知道。

非阻塞:
非阻塞是等待事件,如果事件没发生,不挂起自己
例子:
烧水时,你过来看一眼,水没开,走了,过一会在过来看,没好,这样不断重复,直到水开为止。

同步异步阻塞非阻塞组合

linux 下同步异步,阻塞非阻塞的一些想法_第1张图片

网络IO其实简单分为以下步骤:
在网卡上等待数据–>从内核态拷贝到用户态(拷贝数据)

5种IO模型
linux 下同步异步,阻塞非阻塞的一些想法_第2张图片

同步阻塞:

在我们最开始学习网络编程一定写过同步阻塞IO模型,时刻关注着对方事件,如果对方没有消息则阻塞在read系统调用上。
如上图1部分,网络IO两个步骤一直在blocking。

同步非阻塞:

我们可以将套接字socket设置为非阻塞的,那么就会出现为上图第二种情况,不断的check直到事件发生,它在拷贝数据阶段依旧是阻塞的。没有数据来会阻塞在那里。
第三中情况,I/O multiplexing,select会阻塞在select函数,poll阻塞在poll函数,epoll阻塞在epoll_wait函数,他们第二阶段都是阻塞的。

单独说下I/O multiplexing
网上很多人将epoll归为异步非阻塞的,我认为这是不对的,从概念上来讲,异步,从事件开始前我就不关注此事件了,你完成了告诉我,而epoll不是,如果没有数据它会阻塞在epoll_wait,我想可能有些人从epoll的优点来看感觉epoll的确是异步的,因为epoll_wait每次返回的是就绪的事件,让大家以为“我不用管了,它返回给我的就是就绪事件呀!”,其实是不对的,网络IO前面说了是分为两个步骤的,epoll_wait会阻塞在第二个步骤拷贝数据,那么它还是阻塞的,其中任何一个步骤阻塞都会阻塞。

异步非阻塞:

linux下应当是aio_*一套API了,但linux异步IO支持并不好,网上批评的文章很多。
可参考这篇文章
Linux kernel AIO这个奇葩
异步非阻塞说明我们完全不用关心事件执行过程,事件完成后发消息给我们,我们接受即可,不会阻塞在网卡上,不会阻塞在拷贝数据上。(注意:阻塞在拷贝数据上也是阻塞啊)。

异步阻塞

没听说过,个人认为也没有异步阻塞这一说,异步不可能阻塞,查了资料有人反对贴上了IBM的一篇文章
使用异步 I/O 大大提高应用程序的性能
看了一点觉得就有问题。
他异步阻塞I/O指的是epoll。

最后,上面仅仅是个人的一些看法和观点,我们学习还是要带着审视的眼光,需要有自己判断知识好坏的能力。

如果文章内容有问题,还请指出^_^

你可能感兴趣的:(事件,同步,异步,分析,阻塞)