[剖析muduo网络库]1.IO的阻塞和非阻塞、同步和异步

muduo库作者陈硕老师原话:在处理IO的时候,阻塞和非阻塞都是同步IO,只有使用了特殊的API才是异步IO

[剖析muduo网络库]1.IO的阻塞和非阻塞、同步和异步_第1张图片

如果说的是业务层面上的一个逻辑处理是同步还是异步的时候,那么:

  • 同步:A操作等待B操作做完事情后,得到返回值,继续处理
  • 异步:A操作告诉B操作它感兴趣的事件以及通知方式,A操作继续执行自己的业务逻辑了;等待B监听到相应事件发生后,B会通知A,A开始相应的数据处理逻辑。

[剖析muduo网络库]1.IO的阻塞和非阻塞、同步和异步_第2张图片

  • **同步阻塞:**比如int size = recv(fd,buf,1024,0),如果数据未就绪,recv阻塞当前线程,当数据就绪(fd的数据缓存区中有数据),并且应用程序花时间将缓存区中的数据搬到用户空间定义的buf后,recv返回

  • **同步非阻塞:**比如int size = recv(fd,buf,1024,0),数据未就绪但是recv依然返回,然后根据recv的返回值进行判断,如果size==0&&errno = EAGAIN,那么说明数据还没准备好

  • **异步阻塞:**没有必要,不合理

  • **异步非阻塞:**比如Node.js

模拟面试:阻塞、非阻塞、同步和异步

让你谈谈IO的阻塞与非阻塞,同步与异步(最好是理论+实践举例)

对于一个典型的网络IO调用来说,阻塞与非阻塞,同步与异步都是在描述IO的状态。一个典型的网络IO调用,可以分为两个阶段,即数据准备阶段和数据读写阶段。

我们拿recv()这个系统调用举例, 需要传入的参数主要是sockfd,应用程序缓冲区buf以及buf的大小

  • 在数据准备阶段

    • 如果sockfd工作在阻塞状态下,那么如果sockfd内核的tcp接收缓冲区中没有数据可读,recv就会阻塞当前的调用线程,如果sockfd工作在非阻塞模式状态下,那么revc就会立即返回,然后我们可以根据recv的返回值去判断IO状态,如果返回值size为-1,说明连接中断;size==0 && size == EAGAIN 表明数据未就绪。
  • 数据就绪后,进入数据读写阶段

    • 对于IO同步来说, 应用程序需要自己将数据由内核缓冲区搬到buf里来,这期间应用程序无法执行其他事情
    • 对于异步IO来说,应用程序首先调用系统提供的异步IO接口,比如Linux平台下的aio_read、aio_write,将sockfd, buf以及通知方式告知于内核,这里的通知方式一般有信号和回调函数两种方式,由内核去将数据搬到buf,这期间应用程序可以去执行其他事情,内核将数据搬完后,内核就会按照事先约定的通知方式去通知应用程序,应用程序就可以直接开始处理数据。(异步IO的调用比同步IO的调用复杂)

当然上面提到的同步与异步是对于系统IO而言,如果说到业务逻辑层面的同步与异步(比如登录注册是同步实现还是异步实现)的话:

  • 同步指的是A操作要调用B操作的API接口时,A操作一直等到B操作执行完后,得到返回值,然后继续向下处理
  • 异步指的是A操作把自己感兴趣的事件以及通知方式告知于B,A继续执行自己的业务逻辑,等到B监听到相应事件后,再通知A去执行相应的处理逻辑。

[剖析muduo网络库]1.IO的阻塞和非阻塞、同步和异步_第3张图片

你可能感兴趣的:(muduo网络库,c++,网络)