同步阻塞
recvfrom属于系统调用,应用程序调用 recvfrom,将内核中的数据包复制到用户空间的缓冲区中。
- 等待数据到来的过程,内核收到数据 block
- 从内核缓冲区复制到用户空间应用程序的缓冲区 block
同步非阻塞
设置为 non-blocking的话,如果内核没有数据,recvfrom会返回一个EWOULDBLOCK错误,告诉用户,数据还未准备好,此时并未阻塞。通过轮询来检查内核是否有数据。
在网络IO时候,非阻塞IO也会进行recvform系统调用,检查数据是否准备好,与阻塞IO不一样,"非阻塞将大的整片时间的阻塞分成N多的小的阻塞, 所以进程不断地有机会 '被' CPU光顾"。
I/O复用模型
用户程序老是占用大量cpu来进行轮询的工作,如果将阻塞等待数据的到来交给select这样的管家来执行,select属于内核级别的,让一个管家帮我们轮询是否有数据的到来,可以节省大量cpu的开箱,而且相对同步非阻塞,可以管理多个fd的情况,一旦有可读的fd,就告知用户可以调用recvfrom,进行内核到用户进程地址空间的copy。
信号驱动模型
安装SIGIO信号处理函数,程序继续往下执行,当数据准备好,内核向用户程序发送一个SIGIO信号,应用程序收到后,执行这个信号相对应的回调函数。
以上四种都为同步模型
异步I/O
使用信号驱动I/O时,当网络套接字可读后,内核通过发送SIGIO信号通知应用进程,于是应用可以开始读取数据。有时也称此方式为异步I/O。但是严格讲,该方式并不能算真正的异步I/O,因为实际读取数据到应用进程缓存的工作仍然是由应用自己负责的。
而异步I/O模型是当数据从内核复制到用户程序的缓冲区中,才递交信号,相比信号驱动I/O,I/O的两个阶段都是非阻塞