网络&操作系统-异步,同步,阻塞,非阻塞
异步 & 同步
同步与异步主要从消息通知机制的角度来说。
- 同步:同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。
- 异步:异步是不需要一直等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。
消息通知
消息通知的方式有三种:
- 状态
- 通知
- 回调 如果用状态来通知,那调用者要每隔一段时间检查一次,效率极低 通知和回调效率较高,执行部件几乎不需要做额外的操作。
场景比喻
去银行办理业务
- 同步: 排队等候消息通知
- 异步: 取了号等叫号。(注册了回调机制)
阻塞与非阻塞
阻塞与非阻塞与程序(线程)等待消息通知时的状态(无所谓同步或者异步)有关。
- 阻塞调用:调用结果返回之前,线程一直被挂起,等待消息通知,不处理其他信息。
- 非阻塞调用:在不能立刻得到结果前。函数不会阻塞当前线程,而会立刻返回。但是会增加线程的切换
- 需要综合协调执行时间和切换成本的关系
场景比喻
在银行等业务(不论是排队还是等叫号)
- 阻塞:一直在等,不能干其他事情
- 非阻塞:边干其他事情边等
同步/异步与阻塞/非阻塞
- 同步阻塞 效率最低
- 异步阻塞 异步非阻塞 想想上面银行的例子,效率也都不是很高 可以对fd设置O_NONBLOCK标志位,这样就可以将同步操作变成非阻塞
- 异步非阻塞
同步阻塞和异步非阻塞出现的较多,但不代表同步等于阻塞,异步等于非阻塞。
异步执行的步骤如下:
1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
4)主线程不断重复上面的第三步。