浅析同步异步阻塞非阻塞

先说说这几个词的意思
同步:同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成。
异步:异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,只要自己完成了整个任务就算完成了
阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务
非阻塞:非阻塞调用是指调用结果返回之前,当前线程不会被挂起,能够执行其他业务

关键点:
  同步和异步是与进程相关的,同步与异步主要是从消息通知机制角度来说的。阻塞和非阻塞是与线程相关的,阻塞非阻塞是等待消息通知时的状态角度来说的。
  同步依赖消息的同步返回,异步是通过状态,回调和通知的方式实现的。
  阻塞依赖消息返回前线程挂起,不能执行其余的业务(同步只是逻辑上函数没返回,可以执行一些其余操作的)
  非阻塞依赖消息返回前,线程不会挂起,是激活状态的。

场景举例:

同步与异步:
  去银行办理业务,以前的情况是大家在一个窗口排队(这是不是暴漏年龄),到没到你都得排着队,不能去做别的事情;
现在的情况是到取号机去拿一个号,在到你之前,你甚至可以到银行外面买个东西。
在这里我们每一个办理业务的人相当于一个进程,这就是同步与异步。

阻塞与非阻塞:
  如果上面排队和取号之后,我们什么都不做,只是等待通知到我们去办理业务,那就是阻塞的。
  如果我们这个时候去吃了一波鸡,那就是非阻塞了。

Linux五种IO模型:

 

  从根本上讲I/O操作分为两部分,用户层API调用(内核);内核层完成系统调用(发起I/O请求)
  所以“异步/同步”的是指API调用;“阻塞/非阻塞”是指内核完成I/O调用的模式。

同步阻塞:是用户层的读或写的请求转换成内核的I/O请求,直到I/O请求阻塞(阻塞,读到数据返回,读不到一直等待)结束,才结束用户层的请求。

同步非阻塞(NIO):是用户层的读或写的请求转换成内核的I/O请求,用户层同步,内核I/O非阻塞(读到返回字节,读不到返回-1)。

异步阻塞:把I/O读取细化为订阅I/O事件,实际I/O读写,在“订阅I/O事件”事件部分会主动让出CPU直到事件发生,内核部分I/O请求阻塞。

信号驱动式IO:为异步阻塞的一种,把上述的订阅I/O事件,转换成用信号驱动的方式实现。

异步非阻塞(AIO):用户层的读或写的请求转换成内核的I/O请求,用户层异步,内核I/O非阻塞。不过这种只是看上去很美,Java里的实现方式还是NIO的一套东西。

总结:同步和异步仅仅是关注的消息如何通知的机制,而阻塞与非阻塞关注的是等待消息通知时的状态。
也就是说,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者。

后记:
这是一遍拖了再拖的随笔,其实大部分想写的都写完了,觉得自己没有完全理解这些东西,这个坑还爬不出来,还需要练功啊,希望以后能好好的把这篇更新下。
(总会为拖延症找到理由,这或许就是拖延症的原因,没救啦...)

参考文章:
微信公众号(写程序的康德)文章 透彻Linux(Unix)五种IO模型
简书文章:https://www.jianshu.com/p/aed6067eeac9

posted @ 2018-01-02 10:56  重名  阅读(243)  评论(0编辑  收藏  举报