面试题答案
一键面试阻塞I/O模型工作流程
- 数据获取:在阻塞I/O模型中,当应用程序调用I/O操作(如读取套接字数据)时,进程会被阻塞,一直等待数据准备好。例如在UNIX系统中,应用调用
read
函数读取网络套接字数据,若此时数据尚未到达网络缓冲区,进程会暂停运行,CPU会切换到其他进程执行。 - 数据处理:当数据准备好后(数据到达网络缓冲区且内核将数据复制到用户空间缓冲区),
read
函数返回,进程被唤醒,开始处理数据。
非阻塞I/O模型工作流程
- 数据获取:应用程序调用非阻塞I/O操作(如非阻塞的
read
),即使数据尚未准备好,函数也会立即返回,而不会阻塞进程。例如在Linux系统中,可以通过设置套接字为非阻塞模式(fcntl(sockfd, F_SETFL, O_NONBLOCK)
)来实现。返回值会提示操作结果,若数据未准备好,通常返回-1
且errno
设置为EAGAIN
或EWOULDBLOCK
。应用程序可以继续执行其他任务,而不是等待数据。 - 数据处理:应用程序通过轮询(不断调用非阻塞I/O操作函数)或结合多路复用技术(如
select
、poll
、epoll
)来检查数据是否准备好。当数据准备好后,再次调用相应I/O操作函数(如read
),将数据从内核空间复制到用户空间,然后进行处理。
两者主要区别
- 数据获取时进程状态
- 阻塞I/O:进程在数据准备阶段被阻塞,无法执行其他任务,直到数据准备好。
- 非阻塞I/O:进程在数据准备阶段不会被阻塞,可继续执行其他代码逻辑,提高了CPU利用率。
- 数据处理时机
- 阻塞I/O:数据准备好后立即处理,处理流程相对简单直接。
- 非阻塞I/O:数据准备好后,需通过轮询或多路复用机制检测到数据准备好后才进行处理,增加了检测环节,但能更灵活地管理多个I/O操作。
- 资源利用
- 阻塞I/O:简单直观,但在等待数据过程中,进程占用CPU资源却不执行有效任务,对于高并发场景效率较低。
- 非阻塞I/O:适合高并发场景,能有效利用CPU资源,但实现复杂度较高,轮询方式可能会浪费一定CPU时间片,多路复用机制实现和管理也相对复杂。