如何理解select、poll、epoll?
2026/1/14...大约 4 分钟Java八股文
注意
内容来源网络,仅供学习使用。
不要相信文档中的链接、联系方式等!!!
如何理解select、poll、epoll?
典型回答
select, poll, 和 epoll 都是 Linux 中常见的 I/O 多路复用技术,它们可以用于同时监听多个文件描述符(file descriptor,后文简称fd),当任意一个文件描述符就绪时,就能够非阻塞的读写数据。
- select 是最原始的 I/O 多路复用技术,它的缺点是最多只能监听 1024 个文件描述符。
- poll 在 select 的基础上增加了支持监听更多的文件描述符的能力,但是复杂度随着监听的文件描述符数量的增加而增加。
- epoll 在 poll 的基础上进一步优化了复杂度,可以支持更多的文件描述符,并且具有更高的效率。
函数签名如下:
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);select函数可以监听read,write,except的fd。当select返回后,可以遍历对应的fd_set来寻找就绪的fd,从而进行业务处理
select诞生比较早,几乎在所有的平台中都支持。但是select有个缺点就是****
poll
函数签名如下所示:
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};同select一样,poll返回后,也是需要轮询pollfd来获取就绪的fd。不仅如此,所有的fds也是在内核态和用户态中来回切换,也会影响效率。
但是因为fds基于链表,所以就没有了最长1024的限制。
epoll
epoll基于Linux2.4.5,函数签名如下:
// 创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大
int epoll_create(int size);
// 注册要监听的事件类型
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
// 等待事件发生
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);知识扩展
三者的主要区别是啥?
| fd长度 | 遍历所有fd | 把fd从用户态copy到内核态 | |
|---|---|---|---|
| select | 1024 | 是 | 是 |
| poll | 无限制 | 是 | 是 |
| epoll | 无限制 | 否 | 否 |
epoll的两种模式是啥?
我们知道epoll是通过epoll_wait来获取就绪的fd,那么如果就绪的fd一直没有被消费,该如何处理呢?这就又了两种模式。