一、Linux中的EPOLL模型
首先redis底层使用的是epoll来调用Linux模型来实现NIO多路复用,来实现高并发的过程;
其中epoll是Linux内核为处理大批量文件描述而做了改进的poll,是Linux下多路复用IO接口的增强版,显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率;
epoll无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了,这也是redis,zookeeper,Netty的中NIO高效使用主要内核;
那么select、poll、以及epoll有什么区别?
select;//使用的是链表实现的,文件描述不能超过1024个,但是文件个数多了以后就会出现性能问题
poll;//使用的是链表实现的,文件描述格式没有限制,但是文件个数多了以后就会出现性能问题
epoll;//使用回调的方式实现的,只会对“活跃”的socket进行操作
那么Linux中的epoll主要由三个核心函数来实现:
//用来创建epoll文件描述
int epoll_create(int size);
//用来添加/修改/删除需要侦听的文件描述符及其事件:其中会用到操作系统的中断机制
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
//接收发生在被侦听的描述符上的用户感兴趣的IO事
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
通过以上的三个函数基本就能完成Linux内核中多路复用的基本过程。
二、redis中多路复用的实现过程
首先redis在启动的时候会调用:aeApiCreate这个函数,在这个函数中调用epoll_create方法:
//创建一个epoll instance
state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */
然后在:aeApiAddEvent方法中调用epoll_ctl方法:
//用来添加/修改/删除需要侦听的文件描述符及其事件
if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
最后在:aeApiPoll方法中调用epoll_wait方法:
//接收发生在被侦听的描述符上的用户感兴趣的事件
epoll_wait(state->epfd,state->events,eventLoop->setsize,tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
368

被折叠的 条评论
为什么被折叠?



