在学习UNIX网络编程的时候,一开始分不清 同步 和 异步,所以还是总结一下,理清下他们的区别比较好。
IO分类
IO根据对IO的调度方式可分为阻塞IO、非阻塞IO、IO复用、信号驱动IO、异步IO。
IO操作整个流程分为 可操作判断 和 实际IO操作 两个区间,我们可以称之为两个半程,前半程判断是否可操作,后半程进行实际操作。
其中阻塞IO、非阻塞IO、IO复用、信号驱动IO因为其【实际的IO操作是同步阻塞】的,所以一般把他们归为同步IO,异步IO的实际IO操作是在独立的线程中完成的,所以称为异步IO。
可以看出,所谓同步异步,针对的是后半程的实际IO。在同步IO中,系统并不主动告诉我们任何信息,需要我们去询问,而在异步IO中,系统将主动告诉我们IO已经完成了。
数据流向
数据是如何从用户程序传到网络上的呢?
下面以一个进程从内核接收数据到响应再到对方收到响应的过程为例:
内核读数据
->
推数据到用户态
->
切换到用户态
->
应用程序处理数据并构造响应数据
->
推数据到内核态
->
内核打包数据
->
发送数据
->
对方内核对数据拆包
->
推数据到用户态
IO模型介绍
阻塞IO:服务阻塞在数据接收操作上,直到客户端数据到达并拷贝到本地进程数据区。比如调用系统调用read之后,如果没数据,则一直停留在内核的系统调用中,直到有数据了才将数据从内核拷贝到用户空间之后返回用户态。
非阻塞IO:服务不断地往返于用户态和内核态直接,轮询数据是否可读,一旦可读则阻塞的读取数据到本地进程数据区,属于前半程轮询,后半程阻塞模式。
IO复用:前半程阻塞(select阻塞),但只要有一个IO套接字可用则启动后半程读取进程。
信号驱动IO:前半程是一个异步机制,注册一个信号驱动事件,在数据可读的时候通过SIGIO信号驱动后半程的触发,其和IO复用的区别在于前半程是一个信号驱动机制。
异步IO:调用IO时提供回调函数,IO作为独立线程完成实际读取及准备工作,到数据复制到本地数据区后通过回调函数调用原调用者进行处理。