指进程发起调用后,会被挂起(阻塞),直到收到数据再返回。如果调用一直不返回,进程就会一直被挂起。
不将进程挂起,调用时立即返回成功或错误,可以在一个线程中轮询多个文件描述符是否就绪
遍历集合中的每个文件描述符,判断是否就绪
int select(int nfds,
fd_set *restrict readfds,
fd_set *restrict writefds,
fd_set *restrict errorfds,
struct timeval *restrict timeout);
select
会遍历每个集合的前 nfds
个描述符,分别找到可以读取、可以写入、发生错误的描述符,统称为“就绪”的描述符。然后用找到的子集替换参数中的对应集合,返回所有就绪描述符的总数。timeout
参数表示调用 select
时的阻塞时长。如果所有文件描述符都未就绪,就阻塞调用进程,直到某个描述符就绪,或者阻塞超过设置的 timeout 后,返回。如果 timeout
参数设为 NULL,会无限阻塞直到某个描述符就绪;如果 timeout
参数设为 0,会立即返回,不阻塞。
epoll的监听列表使用红黑树存储,epoll_ctl 函数添加进来的 fd 都会被放在红黑树的某个节点内,而红黑树本身插入和删除性能比较稳定,时间复杂度 O(logN),并且可以存储大量的的fd,避免了只能存储1024个fd的限制;
epoll_ctl 中为每个文件描述符指定了回调函数,并在就绪时将其加入到就绪列表,因此不需要像select一样遍历检测每个文件描述符,只需要判断就绪列表是否为空即可;
判空O(1),判所有O(N)