select的文件描述符集合是位数组->fd_set (线程不安全)一次系统调用
在内核中 select 采用的是轮询的机制来查询就绪 fd ,事件复杂度为 O(N),
然后返回给用户的时候任然需要遍历查询 就绪 fd 事件复杂度也为 O(N)
并且每次调用结束后都会使用一组宏来清理和重新设置 fd_set。
使用三个位图表示三种被监听的描述符,读,写,exp(检查是否有异常条件出现的fd)
将fd加入集合前先复制一份到array,用于fd返回时作为源数据进行判断
支持1024个文件描述符
每次都需要将描述符拷贝到内核去监控
在内核对描述符进行轮行遍历
必须使用select的情况:
1.每个支持网络和非阻塞套接字的平台都支持select,所以它可以跨平台
2.超时时间可以精确到纳秒级,其他两个精确到毫秒级
poll的文件描述符是链表 (线程不安全)当一个文件描述符被添加到等待队列时,另一个进程需要释放掉该fd是不被允许的
将fd和event绑定到pollfd的结构体{fd,要监听的事件,发生事件}中传入内核,内核中使用链表维护
缺点:轮询遍历;返回后需要轮询pollfd来获取就绪描述符 O(n)
epoll底层是红黑树(线程安全)fd被添加到就绪队列后,其他进程可以释放掉它 三次系统调用
epoll完成高性能工作需要和线程池配合使用,epoll负责监听事件,线程池负责具体任务
附简单epoll的使用https://www.cnblogs.com/haippy/archive/2012/01/09/2317269.html
epoll的两种工作模式
EL(阻塞和非阻塞套接字) 多次提醒,直到完成
LT(非阻塞套接字) 只提醒一次