三种I/O模型的对比
简单总结select/poll/epoll三者的区别如下:
select:
- 监听的文件描述符个数有最高上限
- 就绪检查时需要遍历所有事件,效率低
- 内核态和用户态需要内存拷贝,开销大
poll:
- 没有最大连接数的限制,基于链表来实现
- 就绪检查时需要遍历所有事件,效率低
- 内核态和用户态需要内存拷贝,开销大
epoll:
- 没有最大连接数的限制,支持的文件描述符上限是最大可以打开文件的数目,1G内存的机器上是大约10万左右
- 就绪检查时只需要遍历已就绪的事件,效率高
- 内核态和用户态不需要内存拷贝,内核可以直接将就绪事件列表添加到用户提供的内存区
epoll简介
1 | int epoll_create (int __size); |
以上三个是内核提供的epoll的系统调用。
- epoll_create用于创建一个epoll句柄。同时,他会占用一个文件描述符,也就是说,在使用完了之后需要调用close关闭该文件描述符,否则可能导致fd被耗尽。返回值为占用的fd。
- epoll_ctl为epoll的事件注册函数,它不同于select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。
- epoll_wait用于检测和等待激活的事件,有就绪事件后就会被添加到events中
关于上面三个函数更详细的解释可以参考这篇博客
epoll改造服务端
1 |
|