select、poll和epoll的比较
一、select机制
在linux下网络通信中,经常用到select机制,这是一种异步通信的实现方式,select中提供一fd_set的数据结果,实际上是一个long类型的数组, 每一个数组元素都能与一打开的文件句柄建立联系,通常这个句柄并不局限于网络通信中的socket句柄,还包括其他文件、命名管道或设备句柄等。当程序中调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执select()的进程哪一Socket或文件可读或者可写。
select的本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:
1、单个进程可监视的fd数量受到了限制,在32位机器上,他所能管理的fd数量最大为1024。
2、需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大。
3、对socket进行扫描时是线性扫描,当socket文件描述符数量变多时,大量的时间是被白白浪费掉的。
二、poll机制
poll是Linux中的字符设备驱动中有一个函数,Linux 2.5.44版本后已经被epoll所取代。poll机制是用在某些Unix系统中,使用poll()函数用于执行与select()函数同等功能的函数。
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。
相比于select机制,poll机制采用链表来进行文件描述符的存储,因此它并没有最大连接数的限制,但同样存在一些缺点:
1、大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。
2、poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。
三、epoll机制
epoll是Linux内核为处理大批量的句柄而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
epoll会复用文件描述符集合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的电平触发(Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。
相比于poll机制,epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。在fd的数组在用户态和内核地址空间之间复制的问题上,epoll使用mmap减少复制开销。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知。
四、select、poll与epoll的比较
1、支持一个进程所能管理的最大连接数
|
select |
单个进程所能打开的最大连接数有FD_SETSIZE宏定义,其大小是32个整数的大小(在32位的机器上,大小就是32*32,同理64位机器上FD_SETSIZE为32*64),当然我们可以对进行修改,然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试。 |
|
poll |
poll本质上和select没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的 |
|
epoll |
虽然连接数有上限,但是很大,1G内存的机器上可以打开10万左右的连接,2G内存的机器可以打开20万左右的连接 |
2、文件描述符剧增后带来的IO效率问题
|
select |
因为每次调用时都会对连接进行线性遍历,所以随着FD的增加会造成遍历速度慢的“线性下降性能问题”。 |
|
poll |
同上 |
|
epoll |
因为epoll内核中实现是根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。 |
3、消息传递的方式
|
select |
内核需要将消息传递到用户空间,都需要内核拷贝动作 |
|
poll |
同上 |
|
epoll |
epoll通过内核和用户空间共享一块内存来实现的。 |
综上,在选择select,poll,epoll时要根据具体的使用场合以及这三种方式的自身特点,epoll的性能最好。但是考虑到在连接数少并且连接都十分活跃的情况下,select和poll的性能可能会比epoll更好,毕竟epoll的通知机制需要很多函数回调。
select、poll和epoll的比较的更多相关文章
- Linux下select, poll和epoll IO模型的详解
http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...
- I/O复用中的 select poll 和 epoll
I/O复用中的 select poll 和 epoll: 这里有一些不错的资料: I/O多路复用技术之select模型: http://blog.csdn.net/nk_test/article/de ...
- (转)Linux下select, poll和epoll IO模型的详解
Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...
- linux select poll and epoll
这里以socket文件来阐述它们之间的区别,假设现在服务器端有100 000个连接,即已经创建了100 000个socket. 1 select和poll 在我们的线程中,我们会弄一个死循环,在循环里 ...
- Select,poll,epoll复用
Select,poll,epoll复用 1)select模块以列表的形式接受四个参数,分别是可读对象,可写对象,产生异常的对象,和超时设置.当监控符对象发生变化时,select会返回发生变化的对象列表 ...
- 聊聊select, poll 和 epoll
聊聊select, poll 和 epoll 假设项目上需要实现一个TCP的客户端和服务器从而进行跨机器的数据收发,我们很可能翻阅一些资料,然后写出如下的代码. 服务端 void func(int s ...
- [转载] select, poll和epoll的区别
源地址:http://sheepxxyz.blog.163.com/blog/static/61116213201022003513530/ 随着2.6内核对epoll的完全支持,网络上很多的文章和示 ...
- Linux中select poll和epoll的区别
在Linux Socket服务器短编程时,为了处理大量客户的连接请求,需要使用非阻塞I/O和复用,select.poll和epoll是Linux API提供的I/O复用方式,自从Linux 2.6中加 ...
- Linux select/poll和epoll实现机制对比
关于这个话题,网上已经介绍的比较多,这里只是以流程图形式做一个简单明了的对比,方便区分. 一.select/poll实现机制 特点: 1.select/poll每次都需要重复传递全部的监听fd进来,涉 ...
- select,poll 和 epoll ??
其实所有的 I/O 都是轮询的方法,只不过实现的层面不同罢了. 其中 tornado 使用的就是 epoll 的. selec,poll 和 epoll 区别总结 基本上 select 有 3 个缺点 ...
随机推荐
- [原] unity3d动态加载脚本
本文记录如何通过unity3d进行脚本资源打包加载 1.创建TestDll.cs文件 public class TestDll : MonoBehaviour { void Start () { ...
- 【函数式】Monads模式初探——for解析式
for表达式是monad语法糖 先看一组演示样例: case class Person(name: String, isMale: Boolean, children: Person*) val la ...
- Spring-Mybatis --- 配置SqlSessionFactoryBean,整合Spring-Mybatis
要利用Mybatis首先是需要导入mybatis-x.x.x.jar,其次,要整合Spring和Mybatis需要导入mybatis-spring-x.x.x.jar. JAR : mybatis-x ...
- error C4996: Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct
使用VS13 跟 google protocbuf时出现了这个问题:真蛋疼,用别人的东西你就说不安全,用你自己的东西时你怎么不说不安全来着! 解决方案 在protoc 生成的头文件中加上 #pr ...
- 浅谈PostgreSQL的索引
1. 索引的特性 1.1 加快条件的检索的特性 当表数据量越来越大时查询速度会下降,在表的条件字段上使用索引,快速定位到可能满足条件的记录,不需要遍历所有记录. create table t(id i ...
- HTML 水平线
<hr /> 标签可以在 HTML 页面中创建水平线,通常用来分隔文章中的小节 <!DOCTYPE HTML> <html> <body> <p& ...
- U3D各键值说明
KeyCode :KeyCode是由Event.keyCode返回的.这些直接映射到键盘上的物理键. 值 对应键 Backspace 退格键 Delete Delete ...
- Kafka 0.11版本新功能介绍 —— 空消费组延时rebalance
在0.11之前的版本中,多个consumer实例加入到一个空消费组将导致多次的rebalance,这是由于每个consumer instance启动的时间不可控,很有可能超出coordinator确定 ...
- Git的撤销与回滚
1,commit 之前的撤销 未添加至暂存区的撤销(add 之前) git status git checkout . 已添加至暂存区的撤销(add 之后,有或者没有commit操作都可以执行) gi ...
- ARM9通过NFS挂载根文件系统
当开发板启动以后可以通过在超级终端发送命令来配置NFS. 首先得给开发板一个IP地址,用下面的命令配置即可: #ifconfig 192.168.0.10 经过上面的配置以后在各自的终端中应该都能PI ...