epoll编程实例客户端_网络编程:epoll

前言

前面讲了IO多路复用的API,select和poll的缺点是性能不够,客户端连接越多性能下降越明显,epoll的出现解决了这个问题,引用The Linux Programming Interface的一个统计对比如下:

fd数量 poll CPU时间(秒) select CPU时间(秒) epoll CPU时间(秒)

---------------------------------------------------------------------

10 0.61 0.73 0.41

100 2.9 3.0 0.42

1000 35 35 0.53

10000 990 930 0.66

---------------------------------------------------------------------

可以看出fd达到100个以后,select/poll就非常慢了,而epoll即使达到10000个也表现得非常好,因为:每次调用select/poll,内核必须检查所有传进来的描述符;而对于epoll,每次调用epoll_ctl,内核会把相关信息与底层的文件描述关联起来,当IO事件就绪时,内核把信息加到epoll的就绪列表里。随后调用epoll_wait,内核只需把就绪列表中的信息提取出来返回即可。

每次调用select/poll,都要把待监控的所有文件描述符传给内核,函数返回时,内核要把描述符返回并标识哪些就绪,得到结果后还要逐个判断所有描述符,才能确定哪些有事件;epoll在调用epoll_ctl时就已经维护着监控的列表,epoll_wait不需要传入任何信息,并且返回的结果只包含就绪的描述符,这样就不用去判断所有描述符。

从概念上理解epoll是这样的,把要监控的fd的IO事件注册给epoll(调用epoll_ctl),然后调用epoll的API等待事件到达(调用epoll_wait),内核可能对每个fd维护着一个读和写的缓冲区,那么:如果我监控读事件,并且读缓冲区有数据了,epoll_wait就会返回,此时我可以调用read读数据。

如果我监控写事件,并且写缓存区未满,epoll_wait也会返回,此时我可以调用write写数据。

如果fd发生了一些错误,epoll_wait也会返回,此时我根据返回的标志位,就可以知道。

如果我监控读事件 并且有客户端连接进来,epoll_wait就会返回,此时我可以调用accept接受客户端。

epoll的API介绍int epoll_create(int size);

创建一个epoll实例,返回代表实例的文件描述符(fd),size自Linux 2.6.8以后忽略,但必须大于0.

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll控制接口,epfd就是epoll的文件描述符,fd是要操作的文件描述符,op有如下几种:EPOLL_CTL_ADD 注册fd的事件,事件类型在event指定。

EPOLL_CTL_MOD 修改已注册的fd事件。

EPOLL_CTL_DEL 删除fd的事件。

epoll_event有一个events成员,指定要注册的事件类型,比较重要的几个:EPOLLIN fd可读事件

EPOLLOUT fd可写事件

EPOLLERR fd发生错误,这个事件总是会被监控,不必手动增加

EPOLLHUP fd被挂起时,这个事件总是会被监控,不必手动增加,这通常发生在socket异常关闭时,此时read返回0,然后正常的清理socket资源。

epoll_event还有一个epoll_data_t成员,由外部设置自定义数据,以方便后续处理。int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

等待事件发生,如果没有事件发生,线程会被挂起,maxevents指定最大事件数,events外部传入的事件数组,长度应当等于maxevents,当事件发生时,epoll会把事件信息填到这里, timeout指定等待的最大时间, 0表示马上返回,-1表示无限等待。

epoll_wait返回等待到的事件数,返回时,遍历events对fd进行处理。 当epoll不再使用时,应该调用close关闭epollfd。

水平触发和边

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值