谈谈我对同步异步阻塞非阻塞的理解

  这几个概念很长一段时间是我感到困惑,因为很抽象,于是在网上铺天盖地的找通俗易懂的文章,可是看完之后,非但没有明白,反而更加迷惑了。看到最多的就是很多人用人和水壶例子来解释这些东西。我认为这些例子有很大的共同点,就是描述的事情交代清楚了,可是无法跟计算机结合起来说明,人看完之后还是云里雾里。

  废话不多说,谈谈我的理解。

  我认为要想解释清楚这几个概念,必须得从系统内核的角度去考虑。

  操作系统分为用户态和内核态。BIO、NIO、AIO都是在操作系统内核升级的前提下去完成的,如果系统内核不升级,是无法达到的。

  linux系统中,一切皆文件,socket连接都是一个文件,用fd表示,也就是文件描述符。socket建立连接的时候,操作系统会创建一个文件描述符,socket调用accept()的时候,socket会将此连接的文件描述符传给内核的read()方法,然后read一直阻塞调用,知道有新的数据产生,然后返回给accept(),这就是传说中的BIO,也就是阻塞IO。

  随着操作系统内核的迭代更新,内核更新除了select()的系统调用。select可以同时传n个文件描述符,用户态可以把n个文件描述符传给select系统调用,系统内核同时监听n个文件描述符,最后返回只有数据的连接,这就是NIO,也就是非阻塞IO。

  不管是阻塞IO还是非阻塞IO,用户态必须要等待内核态返回,然后才能处理数据,这就是同步。

  如果用户态无需等待内核返回,而是直接去干自己的事,内核返回数据之后,由api得到有没有数据返回,犹豫linux的AIO实现相当复杂,所以linux的AIO一直没有成熟的解决方案,也是一直处于停滞不前的阶段。

  Redis中并没有使用普通的NIO,而是使用epoll。Redis并有用户态和内核态之间拷贝文件描述符的过程,而是直接使用mmap操作共享内存,因此redis的效率比一般的NIO还要高很多。

  以上观点只是本人在学习过程中的一点总结,如有不确之处,欢迎大家批评指正。

猜你喜欢

转载自www.cnblogs.com/kangshen1992/p/12056574.html