您的位置:首页 > 理论基础 > 计算机网络

深入linux网络编程(三):异步阻塞IO —— epoll

2018-03-10 22:09 204 查看

1. 
epoll
的优越性

上一节介绍的
select
有几个缺点:存在最多监听的描述符上限
FD_SETSIZE

每次被唤醒时必须遍历才能知道是哪个描述符上状态
ready
,CPU随描述符数量线性增长
描述符集需要从内核copy到用户态
这几个缺点反过来正是
epoll
的优点,或者说
epoll
就是为了解决这些问题诞生的:没有最多监听的描述符上限
FD_SETSIZE
,只受最多文件描述符的限制,在系统中可以使用
ulimit -n
设置,运维一般会将其设置成20万以上
每次被唤醒时返回的是所有
ready
的描述符,同时还带有
ready
的类型
内核态与用户态共享内存,不需要copy

2. 简述
epoll
的工作过程

2.1 创建

首先由
epoll_create
创建
epoll
的实例,返回一个用来标识此实例的文件描述符。

2.2 控制

通过
epoll_ctl
注册感兴趣的文件描述符,这些文件描述符的集合也被称为
epoll set

2.3 阻塞

最后调用
epoll_wait
阻塞等待内核通知。

3. 水平触发(LB)和边缘触发(EB)

epoll
的内核通知机制有水平触发和边缘触发两种表现形式,我们在下面例子中看一下两者的区别。有一个代表读的文件描述符(
rfd
)注册在
epoll

在管道的写端,写者写入了2KB数据
调用
epoll_wait
会返回
rfd
作为ready的文件描述符
管道读端从
rfd
读取了1KB数据
再次调用
epoll_wait

如果
rfd
文件描述符以ET的方式加入
epoll
的描述符集,那么上边最后一步就会继续阻塞,尽管
rfd
上还有剩余的数据没有读完。相反LT模式下,文件描述符上数据没有读完就会一直通知下去。

4. 
epoll
的两个数据结构

4.1 
epoll_event

struct epoll_event {
uint32_t     events;      /* Epoll events */
epoll_data_t data;        /* User data variable */
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: