Unix网络编程 I/O模型

阻塞式I/O模型

默认情况下,所有的套接字都是阻塞式的。
在这里插入图片描述
上图以recvfrom为例子展示阻塞式I/O。引用程序调用recvfrom系统调用。此时内核中没有数据准备好,于是应用程序被阻塞于recvfrom,进程进入sleep状态。直到内核的缓冲区中准备好了数据,内核缓冲区中的数据将被复制到应用程序缓冲中,复制完成之后,recvfrom才会返回成功。

非阻塞式I/O模型

进程将套接字设置为非阻塞是在通知内核,当所请求的I/O操作非得吧本进程投入睡眠才能完成时,不要吧本程序投入睡眠,而是返回一个错误。
在这里插入图片描述
上图中应用程序反复调用recvfrom系统调用。当内核未准备好,进程并不会阻塞,也不会sleep,而是recvfrom直接返回了一个EWOULDBLOCK错误。当然此时你就可以调用其他函数了,图中继续调用了recvfrom直到内核中的数据准备好了,才将内核缓冲数据复制到应用程序缓冲,recvfrom返回成功。

I/O复用模型

IO复用可以同时关注多个套接字的I/O。我们以select为例子。
在这里插入图片描述
在这张图之前,我们会先告诉select我们所关心的套接字,select会接收相关套接字的I/O信息。
我们调用select系统调用,当内核内无任何套接字的数据准备好时,select会阻塞,直到某些数据到来。当数据到来时,select会记录那些套接字的数据来了(存在一个数组中)。此时就可以使用recvfrom接收相关套接字的数据,recvfrom将内核缓冲区数据复制到应用程序缓冲区后返回成功。

信号驱动式I/O模型

在这里插入图片描述
使用信号驱动式I/O我们首先要开启套接字的信号驱动式I/O功能,并通过sigaction系统调用建立一个信号处理程序,该系统调用将立即返回。进程会继续做自己的工作。当内核中的数据准备好时,内核会发送一个SIGIO信号,我们随后就可以调用recvfrom,将内核缓冲区中的数据复制到应用程序缓冲区,并放回成功。

异步I/O模型

在这里插入图片描述
应用程序调用aio_read函数(POSIX异步I/O函数以aio_或lio_开头),给内核传递文件描述符,缓冲区指针,缓冲区大小和文件偏移。该系统调用立即返回。应用程序继续去做其他事情,不被阻塞。然后,内核会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,内核会给应用程序进程发送一个signal,告诉它read操作完成了。

总结和对比

同步I/O操作:导致请求进程阻塞,直到I/O操作完成。
异步I/O操作:不导致请求进程阻塞。
前四种I/O模型,阻塞式,非阻塞式,I/O复用以及信号驱动式都属于同步I/O。
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章