IO模型 总结

IO的本质是基于操作系统接口来控制底层的硬件之间数据传输,并且在操作系统中实现了多种不同的IO方式(模型),比较常见的有阻塞型IO模型、非阻塞型IO模型、多路复用IO模型

一、阻塞IO

当进程发出IO请求后,阻塞进程(让进程进入睡眠状态),资源就绪后唤醒进程继续执行,如scanf函数

一般默认的IO模型都是阻塞性IO

需要结合多进程/线程,每个进程/线程处理一路IO

缺点:客户端越多,需要创建的进程/线程越多,相对占用内存资源较多

二、非阻塞IO

当进程发出IO请求后,无论资源是否就绪都会立即返回
单进程可以处理,但是需要不断检测客户端是否发出IO请求,需要不断占用cpu,消耗 cpu 资源

实现非阻塞型IO,需要设置 O_NONBLOCK 标志,设置有两种方式
1、可以通过调用 fcntl 函数来进行设置
2、通过open函数来进行设置,一般在打开文件时就需要设置

三、多用复用IO简介

本质上就是通过复用一个进程来处理多个IO请求

基本思想:由内核来监控多个文件描述符是否可以进行I/O操作,如果有就绪的文件描述符,将结果告知给用户进程,则用户进程在进行相应的I/O操作

四、select 多路复用I/O方案

函数原型
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);
函数功能
监控一组文件描述符,阻塞当前进程,由内核检测相应的文件描述符是否就绪,一旦有文件描述符就绪,将就绪的文件描述符拷贝给进程,唤醒进程处理
函数参数
nfds:最大文件描述符加1
readfds:读文件描述符集合的指针
writefds:写文件描述符集合的指针
exceptfds:其他文件描述符集合的指针
timeout:超时时间结构体变量的指针

操作文件描述符集合函数

void FD_CLR(int fd,fd_set *set)
将fd从文件描述符集合中删除
示例代码:使用select函数监控标准输入,如果有输入,则打印相应的信息
int FD_ISSET(int fd,fd_set *set)
判断fd是否在文件描述符集合中
void FD_SET(int fd,fd_set *set)
将文件描述符添加到文件描述符集合中
void FD_ZERO(fd_set *set)
将文件描述符集合清空
参数描述:
fd:文件描述符
set:文件描述符集合的指针

1、select函数理解

 超时时间的说明
        如果timeout之后,文件描述符集合中没有任何就绪的文件描述符,select函数就会返回0
        超时之后,timeout会被select函数修改,表示超时时间已经使用完。
        如果想继续使用超时时间,需要备份之前的struct timeval
        超时之后,表示没有就绪的文件描述符,此时文件描述符集合被赋值为空


        因此,需要将之前的文件描述符集合进行备份

2、多路复用IO-poll

多路复用poll的方式与select多路复用原理类似,但有很多地方不同,下面是具体的对比
        在应用层是以结构体struct pollfd数组的形式来进行管理文件描述符,在内核中基于链表对数组进行扩展;select方式以集合的形式管理文件描述符且最大支持1024个文件描述
        poll将请求与就绪事件通过结构体进行分开
        select将请求与就绪文件描述符存储在同一个集合中,导致每次都需要进行重新赋值才能进行下一次的监控
        在内核中仍然使用的是轮询的方式,与 select 相同,当文件描述符越来越多时,则会影响效率

poll多路复用实现主要调用poll函数

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
函数功能
监控多个文件描述符的变化
函数参数
fds:sturct pollfd结构体指针
nfds:fds结构体的数量
timeout:超时时间,单位为ms

poll 事件说明

事件定义 说明
POLLIN普通数据可读
POLLOUT普通数据可写
POLLRDNORM相当于POLLIN
POLLERR发生错误

3、epoll 基本原理
epoll相对于select与poll有较大的不同,主要是针对前面两种多路复用 IO 接口的不足
select/poll的不足:
        select 方案使用数组存储文件描述符,最大支持1024个
        select 每次调用都需要将文件描述符集合拷贝到内核中,非常消耗资源
        poll 方案解决文件描述符存储数量限制问题,但其他问题没有得到解决
        select / poll 底层使用轮询的方式检测文件描述符是否就绪,文件描述符越多,则效率越低
epoll优点:
        epoll底层使用红黑树,没有文件描述符数量的限制,并且可以动态增加与删除节点,不用重复拷贝
        epoll底层使用callback机制,没有采用遍历所有描述符的方式,效率较高

五、poll和epoll方案图解

1、 select/poll方案

2、 epoll方案

epoll创建需要调用epoll_create函数,用于创建epoll实例

epoll控制函数主要用于文件描述符集合的管理,包括增加、修改、删除等操作。
epoll_ctl函数详细信息如下

函数原型
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
函数参数
epfd:epoll 实例
op:epoll 操作命令字
EPOLL_CTL_ADD:在epoll实例中添加新的文件描述符(相当于向红黑树中添加节点),并将事件与fd关联
EPOLL_CTL_MOD:更改与目标文件描述符fd相关联的事件
EPOLL_CTL_DEL:从epoll实例中删除目标文件描述符fd ,事件参数被忽略
在系统中定义如下:
#define EPOLL_CTL_ADD 1 /* Add a file descriptor to the interface. */
#define EPOLL_CTL_DEL 2 /* Remove a file descriptor from the interface.*/
#define EPOLL_CTL_MOD 3 /* Change file descriptor epoll_event structure.*/

fd:操作的文件描述符

event:struct epoll_event结构体对象指针

epoll_wait 函数:等待文件描述符关联的事件发生

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值