同步、异步、阻塞与非阻塞
- 同步和异步关注的是消息通知的机制
- 阻塞和非阻塞关注的是等待消息时线程的状态
区分
-
如果一直在显示的等待消息的到来,同步
-
如果经过一个消息通知机制,等待消息则是异步
-
在等待消息的时候,如果线程还能做其他事情,则是非阻塞的
-
如果除了等待消息,其他什么事情也不能做,则是阻塞的
-
同步阻塞 坐等待消息到来,而且什么也不做
-
同步非阻塞 坐等待消息的到来,期间还可以做一些其他的事情
-
异步阻塞 等待消息的通知,期间并不做其他事情
-
异步非阻塞 等待消息的通知,期间还做其他的事情
举例
- 下载文件
- 我盯着下载进度,什么也不敢
- 一遍夹手指甲,不时的瞄一眼进度条
- 我什么也不做,等待下载完成叮的一声
- 我剪指甲,等待叮的一声
区别
同步阻塞形式
- 效率是最低的,
- 拿上面的例子来说,就是你专心排队,什么别的事都不做。
- 实际程序中:就是未对fd 设置O_NONBLOCK标志位的read/write 操作;
异步阻塞形式
- 如果在银行等待办理业务的人采用的是异步的方式去等待消息被触发(通知),也就是领了一张小纸条,假如在这段时间里他不能离开银行做其它的事情,那么很显然,这个人被阻塞在了这个等待的操作上面;
- 异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
- 比如select 函数,假如传入的最后一个timeout参数为NULL,那么如果所关注的事件没有一个被触发,程序就会一直阻塞在这个select 调用处。
- 这种方式岂不是很傻
同步非阻塞形式
- 实际上是效率低下的
- 想象一下你一边打着电话一边还需要抬头看到底队伍排到你了没有,如果把打电话和观察排队的位置看成是程序的两个操作的话,这个程序需要在这两种不同的行为之间来回的切换,效率可想而知是低下的。
- 很多人会写阻塞的read/write 操作,但是别忘了可以对fd设置O_NONBLOCK 标志位,这样就可以将同步操作变成非阻塞的了。
异步非阻塞形式
- 效率更高
- 因为打电话是你(等待者)的事情,而通知你则是柜台(消息触发机制)的事情,程序没有在两种不同的操作中来回切换。
- 比如说,这个人突然发觉自己烟瘾犯了,需要出去抽根烟,于是他告诉大堂经理说,排到我这个号码的时候麻烦到外面通知我一下(注册一个回调函数),那么他就没有被阻塞在这个等待的操作上面,自然这个就是异步+非阻塞的方式了。
- 如果使用异步非阻塞的情况,比如aio_*组的操作,当发起一个aio_read操作时,函数会马上返回不会被阻塞,当所关注的事件被触发时会调用之前注册的回调函数进行处理。

Socket IO的形式是会将接收到的数据先缓存在内核缓冲区上,然后再复制到进程的内存中
https://www.jianshu.com/p/aed6067eeac9 什么是异步同步,阻塞非阻塞 https://www.jianshu.com/p/486b0965c296 五种IO模型