[记录]select与epoll

目录:

1. 介绍select实现的特点;

2. 介绍epoll实现的特点;

3. 关于epoll的不足;

 

关于select, epoll,本文没有什么新的内容。只是作为记录,帮助理解。

1. select的实的特点

Select 实现具有如下特点:

1)每次调用select系统调用,都需要从用户空间拷贝数据到内核空间;
2)对于每一个fd(用户可以传送一批fd)调用其对应的设备的poll函数,对于socket来说,就调用tcp_poll函数;并收集设备是否有事件发生;

3)轮询了所有fd后,若没有事件发生,该函数就挂起,直到通知有事件发生,或者超时。

对于3)中,若扫描所有fd后,没有事件发生,该调用线程会挂起,那在什么时候,由谁唤醒该线程呢?这里就需要仔细考察下poll函数了。Poll函数将会将调用的线程挂在设备的对待队列中,当设备有事件发生的时候,就会唤醒等待队列中的线程。这里,就会唤醒调用select系统调用的线程。

从上面可以看出,若用select来实现一个事件循环的话,每次循环都会将fd从用户空间复制到内核空间,并且轮询每一个fd对应的设备状态;这看起来确实不明智。

 

2. epoll实现的特点

从用户空间向内核空间拷贝数据,和轮询设备都是费时操作,对于fd量很多的情况下,select就明显吃力了。Epoll就在这时候诞生了,epoll的实现克服了select的在多fd情况下表现的缺陷;基本原则是采用空间换时间的策略。

1)Epoll将每一个fd所需的数据保存在内核,而不是每次系统调用都需要从用户空间复制数据到内核,只是在fd首次注册的时候复制到内核。这样内核需要空间存储fd所需的数据。

2)epoll摈弃轮询设备的做法,而是在监视的设备等待队列中添加一个等待项。

3)当设备就绪后,等待项中的回调函数会调用。该回调函数将设备事件负责到一个链表中,并且唤醒调用epoll_wait的线程。

从epoll的实现来看,采用空间换时间的策略,去掉了重复从用户空间向内核空间复制数据的操作;采用回调机制,避免了轮询设备。从而epoll在大量fd的情况下,性能明显优于select。

 

3. epoll的不足

最近,在学习libev的代码。在libev的man-page上有这样一段话:

The epoll mechanism deserves honorable mention as the most misdesigned of the more advanced event mechanisms: mere annoyances include 1) silently dropping file descriptors, 2) requiring a system call per change per file descriptor (and unnecessary guessing of parameters), 3) problems with dup, 4) returning before the timeout value, 5) resulting in additional iterations (and only giving 5ms accuracy while select on the same platform gives 0.1ms) and so on. 

原文链接:http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod

关于上述5个不足,目前还没有彻底明白。等明白了后,再将本文补全。

引用:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值