一、这里IO是什么
操作系统设有用户态与内核态,确保系统安全。应用程序默认在用户态运行,而执行如IO操作等底层任务时,需切换至内核态以高效执行。
服务器从网络接收的大致流程如下:
1、数据通过计算机网络来到了网卡
2、把网卡的数据读取到 socket 缓冲区
3、把 socket 缓冲区读取到用户缓冲区,之后应用程序就可以使用
核心就是两次读取操作,五大 IO 模型的不同之处也就在于这两个读取操作怎么交互
二、同步/异步和阻塞/非阻塞
同步与异步:这是应用层的关键概念。同步指调用函数后需等待其执行完毕再继续,而异步则允许立即执行后续操作,并在另一线程中处理被调用的函数。重点在于线程间的协作与消息通信机制。同步IO涉及发出调用后亲自等待结果,而异步IO则在整个过程中无需参与,直至数据准备就绪。阻塞与非阻塞:在硬件层面,阻塞指CPU暂停当前任务处理其他进程,如IO操作;非阻塞则保持执行,不切换进程。核心在于CPU是否被“暂停”,反映到应用层面即线程是否“被”挂起。三、五种io模型
1.阻塞io
应用调用`recvfrom`读取数据时,系统调用将阻塞直到数据包到达并复制到应用缓冲区或发生错误。此期间,进程保持阻塞状态,即阻塞IO。内核准备数据前,系统调用将持续等待。所有套接字默认采用阻塞模式,确保数据完整接收。
应用进程向内核发起recfrom读取数据内核进行准备数据报(此时应用进程阻塞)内核将数据从内核负复制到应用空间。复制完成后,返回成功提示2.非阻塞io
应用申请读取数据时,若内核数据未就绪,系统会立即通知应用并返回EWOULDBLOCK错误码,避免应用无谓等待。非阻塞IO要求程序员通过循环方式不断尝试读写文件描述符,确保高效的数据处理。
应用进程向内核发起recvfrom读取数据。内核数据报没有准备好,即刻返回EWOULDBLOCK错误码。应用进程再次向内核发起recvfrom读取数据。内核倘若已有数据包准备好就进行下一步骤,否则还是返回错误码内核将数据拷贝到用户空间。完成后,返回成功提示3.io多路复用
线程监控多网络请求(通过fd文件描述符),实现数据状态查询。一旦数据就绪,立即分配线程读取,确保高效处理网络数据流。
应用进程向内核发起recvfrom读取数据内核进行准备数据报(此时应用进程阻塞)内核倘若已有数据包准备好则通知应用线程内核将数据拷贝到用户空间完成后,返回成功提示下面给出一个应用系统和内核之间的流程图
4.信号驱动
信号驱动IO在sigaction调用时建立SIGIO信号联系,内核数据就绪时通过SIGIO通知线程。线程收到可读信号后,发起recvfrom请求读取数据。此模型下,应用线程发出监控信号后可立即返回,无阻塞,因此单个线程能同时监控多个文件描述符(fd),显著提高效率。
应用进程向内核发起recvfrom读取数据内核进行准备数据报,即刻返回内核倘若已有数据包准备好则通知应用线程应用进程向内核发起recvfrom读取数据内核将数据拷贝到用户空间完成后,返回成功提示下面给出一个应用系统和内核之间的流程图
5. 异步IO:应用仅发送读取请求后即刻返回,内核建立信号联系。数据就绪时,内核自动将数据复制到用户空间。完成所有操作后,内核通知应用,实现高效的数据传输与响应。
应用进程向内核发起recvfrom读取数据内核进行准备数据报,即刻返回内核收到后会建立一个信号联系,倘若已有数据包准备好,内核将数据拷贝到用户空间完成后,返回成功提示四、五种io对比
前四种模型在数据读取阶段均为阻塞操作,属于同步IO。而异步IO模型在整个IO流程中均保持非阻塞状态,实现了真正的异步处理。
-对此,您有什么看法见解?-
-欢迎在评论区留言探讨和分享。-