select、poll、epoll之间的区别总结
2015-08-04 22:08
309 查看
这个问题面试经常会被问道,赶紧总结一下
select、poll、epoll都是IO多路复用的机制,先是监听多个文件描述符FD,一旦某个FD就绪,就可以进行相应的读写操作。但是select、poll、epoll本质都是同步I/O,他们都需要在读写事件就绪之后自己负责读写,即这个读写过程是阻塞的
1 select/poll
select缺点:
【1】每次调用select都需要把fd从用户态拷贝到内核态,开销比较大
【2】每次都需要在内核遍历传入的fd
【3】select支持文件数量比较小,默认是1024
poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,就不赘述了
2 epoll牛在哪里?
select/poll只提供了一个函数,selct/poll函数,但是epoll一下子就提供了3个函数,真是人多力量大,难怪这么强,如下3个函数:
epoll_create,epoll_ctl和epoll_wait,epoll_create是创建一个epoll句 柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。
优点:
【1】每次注册新事件到epoll句柄都会把所有的fd拷贝进来,而不是在epoll_wait中重复拷贝,这样确保fd只会被拷贝一次
【2】epoll不是想select/poll那样每次都把fd加入等待队列中,epoll把每个fd指定一个回调函数,当设备就绪时,唤醒等待队列的等待者就会调用其的回调函数,这个回调函数会把就绪的fd放入一个就绪链表。epoll_wait就是在这个就绪链表中查看有没有就绪fd
【3】epoll没有fd数目限制
总结:
(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用 epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在 epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的 时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要 一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内 部定义的等待队列)。这也能节省不少的开销。
select、poll、epoll都是IO多路复用的机制,先是监听多个文件描述符FD,一旦某个FD就绪,就可以进行相应的读写操作。但是select、poll、epoll本质都是同步I/O,他们都需要在读写事件就绪之后自己负责读写,即这个读写过程是阻塞的
1 select/poll
select缺点:
【1】每次调用select都需要把fd从用户态拷贝到内核态,开销比较大
【2】每次都需要在内核遍历传入的fd
【3】select支持文件数量比较小,默认是1024
poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,就不赘述了
2 epoll牛在哪里?
select/poll只提供了一个函数,selct/poll函数,但是epoll一下子就提供了3个函数,真是人多力量大,难怪这么强,如下3个函数:
epoll_create,epoll_ctl和epoll_wait,epoll_create是创建一个epoll句 柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。
优点:
【1】每次注册新事件到epoll句柄都会把所有的fd拷贝进来,而不是在epoll_wait中重复拷贝,这样确保fd只会被拷贝一次
【2】epoll不是想select/poll那样每次都把fd加入等待队列中,epoll把每个fd指定一个回调函数,当设备就绪时,唤醒等待队列的等待者就会调用其的回调函数,这个回调函数会把就绪的fd放入一个就绪链表。epoll_wait就是在这个就绪链表中查看有没有就绪fd
【3】epoll没有fd数目限制
总结:
(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用 epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在 epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的 时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要 一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内 部定义的等待队列)。这也能节省不少的开销。
相关文章推荐
- 分布式系统与集群的区别
- ARMA建模以及卡尔曼滤波
- JavaScript之HTML DOM
- 初步学习MVC的白痴问题的解决记录(一)
- 函数节流
- !HDU 4345 置换群的环长有多少种-dp
- hdu_5551_多校联赛5_1009
- cause:Permission Denial: receiving Intent act=android.provider.Telephony.SMS_RECEIVED
- 多线程1
- Count the Trees 典型卡特兰数
- 【Objective-C编程】import、include及@Class的孽缘
- VistualStudio 2005 设置PowerBuilder12.5 PBNI编绎命令行。
- 浅谈WebView
- Docker 容器日志的那些事儿
- 【Mac版】安装 Android Studio 及配置环境变量步骤
- 没做过编译器就是被人欺——从一道变态的i++题猜编译器的行为(表达式从左往右扫描,同一变量相互影响)
- 关于foreach的一个BUG
- leetcode面试准备:Count Complete Tree Nodes
- Struts拦截器拦截未登录的操作
- sudo 问题