select和epoll的总结

select和epoll

是解决I/O多路复用的机制

FD_ZERO(fd,fdset);
FD_SET(fd,fdset);
FD_ISSET(fd,fdset);
select(fdmaxplus1,readfds,writefds,errorfds,timeval)
1、只要三个fd集至少有一个就绪的文件描述符,则返回,否则阻塞到timeout
2、其本质是利用阻塞的方式处理多个非阻塞的通讯请求。
3、监控的fd的数目有限 1024/2048和宏有关,改变需要重新编译内核
4、每次都要把三个fds拷贝到内核中,内核从头遍历所有的fds,无差别遍历0(n),
调用sys_select,首先会把readfds,writefds,errorfds拷贝到内核中,调用poll对readfds,writefds,errorfds进行处理【一次poll】,把结果存放到临时的变量中,如果变量中没有就绪的文件描述符,则睡眠到超时,睡眠结束后再轮询一次,并返回结果;
如果,有就绪文件描述符,则直接返回。再把结果拷贝到用户空间。
5、用户端每次也需要遍历fds,找到就绪的fds。
总结:系统开销会随着fds的增加成线性增长。网络不稳定的情况下,系统开销会更大。

int epoll_create(int pollmax);
int epoll_ctl(int epollfd,int opt,int fd,struct epoll_event * event);
int epoll_wait(int epollfd,struct epoll_event *event_array,int pollmax,int timeout);

epoll 的两种工作模式:
et,lt:et为非阻塞模式,只相应一次,文件描述符就绪后,epoll_wait返回后如果没被处理,下次不会保留到就绪队列中。
lt为阻塞,非阻塞可选,没有上述的问题。
1、监控的文件描述符为2^16
2、其本质是利用阻塞的方式处理多个非阻塞的通讯请求。
3、不用每次都把描述符信息拷贝到内存中,只要添加一次描述符和epoll_event的对应信息就可[利用map方式]
4、不是轮询机制。每个描述符都有一个注册回调函数,当对应的事件发生时,回调函数会把事件描述符放到就绪链表中,然后返回。
5、用户端返回的都是事件发生的描述符,不用遍历。
6、系统开销不会随fds数目的增长而显著增长。

你可能感兴趣的:(c基础知识)