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

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 */
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值