select、poll、epoll区别
select和poll
- 都是IO多路复用的实现,select和poll类似,对所有的IO请求进行轮询(对fds数组遍历),当描述符(fd)就绪(读写就绪),就通知应用程序进行相应操作,超时就返回。
- select和poll区别:select基于fds数组存储,默认最大连接数是1024,poll基于链表存储,没有最大连接数限制。他们的共同缺点是大量的fds数据被整体复制与用户态和内核地址之间。
epoll:poll升级版。
- 没有最大连接数限制,通过事件注册(通过epoll_ctl注册fd,epoll_wait接受就绪通知)和回调实现高效(不需要轮询)读写操作。
- 用文件描述符管理描述符,存入事件表(红黑树实现)中。
- epoll工作模式:支持边缘触发和水平触发(java.nio),边缘触发是就绪后只通知一次,水平触发是不断地通知是否就绪。优点是:
- epoll能支持较大连接数;
- 效率高(非轮询,而是基于事件回调);
- 用mmap(memory map)拷贝减少复制开销。索引结构:epoll使用红黑树去监听并维护所有epoll_ctl传进来的socket(文件描述符)。就绪列表:epoll使用双向链表来维护就绪队列(管理描述符),epoll_wait只需要监听这个就绪队列有无数据返回即可
? 怎么维护就绪链表?红黑树高效体现在哪?
执行epoll_ctl时,socket放入红黑树,并给内核处理注册一个回调函数,一旦数据到达并中断,就把网卡数据copy到内核,socket插入就绪链表,拿着句柄id就去红黑树里快速找到并删除。就算监听了百万句柄,每次只需要返回少数就绪的句柄即可。
? 使用场景:较大连接数使用epoll,较少连接数适合用select和poll,因为epoll需要经过很多回调,可能效率不及select和poll。
select、poll、epoll
原文:https://www.cnblogs.com/brightdagger/p/14688583.html