Linux的I/O复用接口select和epoll
文章图片
select采用轮询方式处理连接,epoll是触发式处理连接。
select select 能监控的描述符个数由内核中的FD_SETSIZE限制,仅为1024,这也是select最大的缺点,因为现在的服务器并发量远远不止1024。即使能重新编译内核改变FD_SETSIZE的值,但这并不能提高select的性能。
每次调用select都会线性扫描所有描述符的状态,在select结束后,用户也要线性扫描fd_set数组才知道哪些描述符准备就绪,等于说每次调用复杂度都是O(n)的,在并发量大的情况下,每次扫描都是相当耗时的,很有可能有未处理的连接等待超时。
每次调用select都要在用户空间和内核空间里进行内存复制fd描述符等信息。
poll poll使用pollfd结构来存储fd,突破了select中描述符数目的限制。
与select的后两点类似,poll仍然需要将pollfd数组拷贝到内核空间,之后依次扫描fd的状态,整体复杂度依然是O(n)的,在并发量大的情况下服务器性能会快速下降。
epoll epoll维护的描述符数目不受到限制,而且性能不会随着描述符数目的增加而下降。
服务器的特点是经常维护着大量连接,但其中某一时刻读写的操作符数量却不多。epoll先通过epoll_ctl注册一个描述符到内核中,并一直维护着而不像poll每次操作都将所有要监控的描述符传递给内核;在描述符读写就绪时,通过回掉函数将自己加入就绪队列中,之后epoll_wait返回该就绪队列。也就是说,epoll基本不做无用的操作,时间复杂度仅与活跃的客户端数有关,而不会随着描述符数目的增加而下降。
【Linux|Linux的I/O复用接口select和epoll】epoll在传递内核与用户空间的消息时使用了内存共享,而不是内存拷贝,这也使得epoll的效率比poll和select更高。
推荐阅读
- 服务器架构|ansible常用模块详细整理(批量管理模块功能)
- 如何在Ubuntu 16.04中使用命令行CLI安装ClamAV并扫描病毒
- 如何安装和使用Exa,这是Ubuntu 16.04中ls命令的现代替代品
- 如何使用CLI检查Ubuntu Server 16.04中的系统规格
- 如何在Ubuntu 16.04中实现软件RAID 1阵列(镜像)
- 如何在Ubuntu 16.04中安装MongoDB
- 如何下载Ubuntu更快地发布ISO文件(加速下载)
- Linux|【Linux篇】第十六篇——多线程(四)(读写锁+线程池)
- Linux|【Linux篇】第十三篇——多线程(一)(线程概念+线程控制)