典型的一次IO的两个阶段是什么?
数据准备 和 数据读写。
网络IO阶段1——数据准备:
阻塞和非阻塞状态
recv方法示例:
int size = recv(sockfd, buf, 1024, 0);
如果sockfd上没有准备数据,那么调用IO方法的线程会进入阻塞状态;
而非阻塞不会改变线程状态,根据size返回值值来判断情况:
size == -1 && errno = EAGAIN // 一个正常的非阻塞返回
size == 0 // 对端关闭了连接
size > 0 // 返回的就是接收数据的大小。
网络IO阶段2——数据读写:
同步 和 异步
如果数据就绪,开始进行读写,应用程序这边的recv会花自己的时间,从内核缓冲区中读数据,拷贝到recv的buf里,这个过程应用程序是一直等待拷贝完成的,完不成就一直阻塞在那个位置,所以是同步操作。
而异步,是把sockfd,buf和一个信号或回调的通知方式告知内核,内核将数据拷贝到buf,这个过程应用程序不参与,可以去做其他事情,拷贝完成后,内核根据这个通知方式告知应用程序,这个操作就是异步。异步一般都是调用内核中aio的接口:
业务层面的一个逻辑处理是同步还是异步?
A操作等待B操作做完事情,得到返回值,继续处理
A操作告诉B操作它感兴趣的事件以及通知方式,A操作继续执行自己的业务逻辑了;等B监听到相应事件发生后,B会通知A,A开始相应的数据处理逻辑。
陈硕大神原话:在处理 IO 的时候,阻塞和非阻塞都是同步 IO。只有使用了特殊的 API 才是异步
IO。
一个典型的网络IO接口调用,分为两个阶段,分别是“数据就绪”和“数据读写”,数据就绪阶
段分为阻塞和非阻塞,表现得结果就是,阻塞当前线程或是直接返回。
同步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都
是由请求方A自己来完成的(不管是阻塞还是非阻塞);异步表示A向B请求调用一个网络IO接口
时(或者调用某个业务逻辑API接口时),向B传入请求的事件以及事件发生时通知的方式,A就
可以处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结
果。