首页  

select poll epoll 区别     所属分类 architecture 浏览量 1508
IO多路复用
监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),通知程序进行相应的读写操作。


select 时间复杂度O(n)
仅仅知道有IO事件发生,但不知道是哪几个,只能无差别轮询所有通道

poll   时间复杂度O(n)
本质上和select没有区别,将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 
但是没有最大连接数限制,因为基于链表存储

epoll  时间复杂度O(1)
可以理解为event poll  , epoll会把哪个流发生了怎样的IO事件发出通知
事件驱动 


select,poll,epoll本质上都是同步IO,在读写事件就绪后需要自己负责进行读写,也就是说这个读写过程是阻塞的,
而异步IO则无需自己负责进行读写,异步IO的实现会负责把数据从内核拷贝到用户空间。

 IO模式 Proactor与Reactor  
  


select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。 缺点

1 单个进程可监视的fd数量有限制 
  /proc/sys/fs/file-max   32位机默认1024  64位机默认2048

2 对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低:
  当套接字比较多的时候,全部遍历一遍 ,会浪费很多CPU时间 
3 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大


poll 水平触发 ,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd


epoll有EPOLLLT和EPOLLET两种触发模式 
LT 水平触发
ET 边缘触发 

epoll优点
1 没有最大并发连接限制,能打开的FD上限远大于1024(1G内存能监听约10万个端口)
2 效率提升,非轮询方式,不会随着FD数目的增加导致效率下降。只有活跃可用的FD才会调用callback函数
3 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递,使用mmap减少复制开销


消息传递方式 select:内核需要将消息传递到用户空间,需要内核的拷贝动作; poll:同上; epoll:通过内核和用户空间共享一块内存来实现,性能较高; 文件句柄剧增后带来的IO效率问题 select:因为每次调用都会对连接进行线性遍历,所以随着FD剧增后会造成遍历速度的“线性下降”的性能问题; poll:同上; epoll:由于epoll是根据每个FD上的callable函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll不会对性能产生线性下降的问题,如果所有socket都很活跃的情况下,可能会有性能问题; 一个进程所能打开的最大连接数 select: 单个进程所能打开的最大连接数,是由FD_SETSIZE宏定义的,其大小是32个整数大小(在32位的机器上,大小是3232,64位机器上FD_SETSIZE=3264), 可以对其进行修改,然后重新编译内核,但是性能无法保证,需要做进一步测试; poll:本质上与select没什么区别,但是他没有最大连接数限制,他是基于链表来存储的; epoll:虽然连接数有上线,但是很大,1G内存的机器上可以打开10W左右的连接;

上一篇     下一篇
netty ByteBuf 使用

dubbo实例

IO模式 Proactor与Reactor

netty ByteBuf vs java NIO ByteBuffer

netty高性能之道

PooledByteBufAllocator跟踪调试