7.1 I/O 处理方式
7.1.1 I/O处理的五种模型
- 阻塞I/O模型
- 若所调用的 I/O 函数没有完成相关的功能就会使进程挂起,直到相关数据到达才会返回。如 终端、网络设备的访问。
- 非阻塞模型
- 当请求的 I/O 操作不能完成时,则不让进程休眠,而且返回一个错误。如 open read write 访问
- I/O 多路转接模型
- 如果请求的 I/O 操作阻塞,且他不使真正阻塞 I/O,而且让其中一个函数等待,在这期间,I/O 还能进行其他操作。如 select 函数
- 信号驱动 I/O 模型
- 在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来,从而启动 I/O
- 异步 I/O 模型
- 在这种模型下,当一个描述符已准备好,可以启动 I/O,进程会通知内核。由内核进行后续处理,这种用法现在较少
7.1.2 非阻塞I/O
- 低速系统调用时,进程可能会阻塞
- 非阻塞I/O确定操作(read, open, write)不阻塞,如果操作不能完成,则出错返回
- 设定非阻塞方式
- 使用 open 打开文件,设置 O_NONBLOCK 标志
- 如果一个文件已经打开,则使用 fcntl 修改文件状态标志为 非阻塞
7.1.3 例子
nonblock_read.c
1 /* 从标准输入读取信息,然后在屏幕上输出 2 * 测试: 3 * (1)在睡眠 5s 内 按ctrl + d 屏幕会输出 read finished 4 * ctrl + d 是给程序发送读取结束的信号,即读到了文件末尾 5 * (2)运行程序后,等待5s 输出 read error,程序不会阻塞在那里,没有输入,size < 0 6 * (3)在5 s 内输入字符,会正常输出字符 7 */ 8 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <unistd.h> 13 #include <string.h> 14 #include <errno.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <fcntl.h> 18 #include "io.h" 19 20 int main(int argc, const char *argv[]) 21 { 22 char buff[4096] = {'