一、文件事件
1、组成四部分
1)套接字:每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件
2)I/O多路复用程序:监听多个套接字,并向温江分派器传送那些发生了事件的套接字
I/O多路复用的功能鞥都是通过包装常见的select、epoll、evport和kqueue这些I/O多路复用函数库实现。
3)文件事件分派器:接收I/O多路复用程序传来的套接字,并根据套接字产生的事件类型,调用相应的事件处理器。
4)事件处理器(多个)
1、连接应答处理器
2、命令请求处理器
3、命令回复处理器
...
二、时间事件
1、组成部分
所有时间事件都放在一个无序链表中,每当时间执行器运行时,就遍历整个链表,查找已到达的时间事件,并调用响应的事件处理器。
注意:新的时间总是插入到链表的表头,按照ID逆序排序,而无序指的是不按when(时间)属性进行大小排序。
三、调度与执行
def aeProcessEvents(): //获取到达时间离当前时间最接近的时间事件 time_event = aeSearchNearestTimer() //计算最接近的时间事件距离到达还有多少毫秒 remaind_ms=time_event.when - unix_tx_now() //如果时间已到达,那么remaind_ms的值可能为负数,将它设定为0 if remaind_ms < 0: remaind_ms =0 //根据remaind_ms的值,创建timeval结构 timeval = create_teimeval_with_ms(remaind_ms) //阻塞并等待文件事件发生,最大阻塞时间由传入的timeval结构决定 //如果remaind_ms的值为0,那么aeApiPoll调用之后马上返回,不阻塞 aeApiPoll(timeval) //处理所有已产生的文件事件 processFileEvents() //处理所有已到达的时间事件 processTimeEvents()
1、aeApiPoll最大阻塞时间由到达时间最接近当前时间的时间事件决定,这个方法避免服务器对时间事件进行频繁的轮询。
2、因文件事件随机出现,如果等待并处理完一次文件事件之后,仍未有任何时间事件到达,那么服务器将再次等待并处理文件事件。最终时间事件设置的时间到达,则开始处理时间事件。
3、对文件事件和时间事件的处理都是同步、有序、原子地执行的,服务器不会中途中断事件处理,也不会对事件进行抢占。
4、因为时间事件在文件事件之后执行,并且事件之间不会抢占,所以时间事件的实际处理时间会比设定的时间稍晚一点。
本文来自博客园,作者:快牵着我的袜子,转载请注明原文链接:https://www.cnblogs.com/socks/p/16083972.html