`
DiaoCow
  • 浏览: 241761 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

《Redis源码学习笔记》事件库

阅读更多
《Redis源码学习笔记》文章列表

Redis没有使用第三方事件库来处理socket(譬如Libevent),而是自己实现了一个非常精巧的事件库(加上注释不到600行代码),这使得我们可以更加专注于Redis本身代码的阅读,而不必陷于三方库的学习和使用(我自己就是因为该原因选择学习Redis而不是memcache);同时阅读Redis自带的事件库也可以让我们一窥类似Libevent这样的事件库内部实现机制;

Redis事件库中的所有函数几乎都是以ae开头(原因不得而知),其中最重要的就是aeEventLoop对象,它充当着“事件处理器”角色:


其中“文件事件”是一个数组,存放当前Redis所有连接的客户端描述符,而“时间事件”则是一个链表,用来存放计划任务;

事件处理器循环流程由于图片较大,缩放较为模糊,请双击打开查看原图):


整个执行流程的伪代码:
def aeMain(aeEventLoop):
	# 开始事件循环
	while (not aeEventLoop.stop):
		aeProcessEvents(aeEventLoop, AE_ALL_EVENTS)

def aeProcessEvents(aeEventLoop, flags):
	# 是否需要处理时间事件
    if flags & AE_TIME_EVENTS:
    	# 获取最近一个即将到达的时间事件
        arrived_time = aeEventLoop.timeEvents.getNearestArrivedTime()
        if (arrived_time < now_time):
        	# 若最近一个时间事件的arrived_time小于当前时间(说明需要立即执行),则设置文件事件为非阻塞
            tvp.sec = 0 
            tvp.usec = 0 
        else:
        	# 否则取两者的时间间隔,作为文件事件的最大阻塞时间
            tvp.sec = arrived_time.sec - now_time.sec
            tvp.usec = arrived_time.usec - now_time.usec 
    else
    	# 文件事件是否阻塞
        if flags & AE_DONT_WAIT:
            tvp.sec = 0 
            tvp.usec = 0 
        else :
            tvp = null 

    # 处理文件事件(IO多路复用)
    # 若此时没有描述符就绪,tvp的值决定阻塞行为(立即返回?阻塞一段时间?一直阻塞下去?)
    aeEventLoop.fileEvents.poll(tvp)

    # 处理达到的时间事件
    if (flags & AE_TIME_EVENTS): 
        aeEventLoop.timeEvents.processArrived()                                                                                                                       

更详细细节,请看:ae.h  ae.c

总结:
1. 了解文件事件和时间事件的概念;
2. 了解Redis事件库运行流程;

  • 大小: 9.3 KB
  • 大小: 29.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics