阻塞、非阻塞、同步、异步
典型的一次IO的两个阶段:数据准备和数据读写
数据准备:阻塞、非阻塞(根据系统IO操作的就绪状态)
数据读写:同步、异步(根据应用程序和内核的交互方式)
数据准备:
IO阻塞:以recv函数为例,int size = recv(sockfd,buf,1024,0),如果sockfd设置的成阻塞方式,线程会被一直阻塞在recv函数上
IO非阻塞:若sockfd设置成非阻塞方式,线程直接返回一个返回值,不会改变线程的状态,会造成cpu的空转;若size == -1 && errno == EAGAIN ,表明sockfd上无网络事件发生,以非阻塞方式返回;若size == 0,网络对端关闭了连接;若size > 0 ,表明读到了size大小的数据
数据读写:
IO同步:IO同步是指A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都是由请求方自己完成的,程序从TCP缓冲区读出数据的过程,数据是由“用户”自己搬运的而非操作系统内核
IO异步:IO异步是指A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),向B传入请求的事件以及事件发生时通知的方式,A就可以处理其他逻辑了,当B监听到事件处理完毕后,会用事先约定好的方式,通知A处理结果。如当有网络事件发生时,应用程序调用recv异步io接口,提供给操作系统 sockfd,buffer 以及sigio信号,之后应用程序可以继续执行任务;而当操作系统将数据从TCP缓冲区搬运到buffer后,会用sigio信号通知用户态的应用程序(数据由操作系统内核搬运)
业务层面区分同步异步的处理逻辑:
同步:A操作等待B操作做完事情,得到返回值,继续处理
异步:A操作通知B操作其想要的事件以及通知方式,A操作继续执行自己的业务逻辑;等B监听到相应事情发生后,B会通知A,A开始相应的数据处理逻辑
“在处理IO的时候,阻塞非阻塞都是同步IO,只有使用了特殊的API才是异步IO”