memcache 线程模型

Mempool 采用主线程+工作线程的模型,主进程主要是:1创建工作线程 2接受连接并把任务分配给工作线程。

子进程主要做具体的工作:解析请求,处理请求。

 

 

 

 

 

一  创建工作线程

先来看源代码

整个过程:

1 初始化主线程的变量

 

2创建和初始化所有工作线程的资源

 

3 启动工作线程

 

4 等待所有工作线程创建完成。

 

我们可以看到为每个线程创建管道的过程,其它的初始都是在函数setup_thread中完成,我们来看看它具体做些什么事情

整个过程

1 创建libevent,并进行初始化,并加入监听的事件

 

2  创建工作线程的连接队列

 

3 初始化互斥锁和后缀缓冲

 

 

这样所有的工作线程都运行起来了,各自干各自的活。

 

问题:

 

1 为什么主线程需要等到所有工作线程启动完成了才去干自己的事情?

 

是不是防止下面情况发生: 主线程去接受客户端的请求,并把任务分发给一个工作线程,而该线程又没有完成启动,就会出错??理解错了希望大家指正。

 

 

 

 

 

 

二  主线程接受请求并分发给工作线程

 

当主线程完成了工作线程的启动,就开始进入自己的正常工作了:循环的调用libevent,是否有连结到来,如果有,那么通过简单的round robin 选择一个线程进行具体的工作。

 

首先主线程调用server_socket函数,来启动监听的socket。具体在conn_new函数中通过调用event_set把监听事件处理函数设置为 event_handler ,这样当有外部的连接过来的时候,就会直接调用event_handler

 

而在event_handler中,直接调用drive_machine来处理具体事件。

 

最后我们来看看drive_machine 干什么事情,其实这个函数就是根据连接的状态进行不同的处理,比如我们连接过来的时候,状态就是 conn_listening:

 

就是接受连接,并设置socket为非阻塞,最后调用 dispatch_conn_new 处理

 

 

 

从自由链表中获取一个连接,并选择一个工作线程,把连接挂载到工作线程的连接队列中,最后通过管道通知工作线程,工作线程就能触发一个事件,开始工作。

 

 

 

 

 

 

三  工作线程

 

当主线程通过管道发送一个字节的数据的时候,工作线程通过libevent会触发事件,直接调用thread_libevent_process 函数

 

 

这个函数就是读取一个字节数据,防止重复触发事件,再去调用cq_pop ,从线程的等待队列中得到一个连接(socket分装),通过调用conn_new来创建一个连接,在conn_new中主要创建一个连接,并往libevent中添加监听的事件,这样可以监听来自客户端的数据.当有数据来的时候,和前面一样会去调用drive_machine函数,根据连接的状态进行不同的处理。

        所以工作线程而言,会触发两类事件,一个来自管道(主线程),一个来自socket(客户端的),前者在刚接受一个新的请求时触发,并且只有一次, 后者有客户端出发,可以多次。并且前者的触发才往libevent中添加后者监听事件,所以后者一定在前者之后。  

 

 

 

 

 

 

总结:

 

 1 通知直接使用libevent,简化了异步编程

              

 2 通过主线程和工作线程,使每个角色的任务简单了。主进程和工作线程通过简单的管道实现通信息,保证了系统的高效。

 

 3 工作线程的选择通过简单的 round robin, 对于cache这种业务简单的应用,具有很好的性能。

 

 4  运用很多“池”的方式,提交资源分配效率(会有少量的浪费)

 

 

 

 

参考

 

http://www.javaeye.com/topic/344172    Memcached源码分析(线程模型)

 

http://www.javaeye.com/topic/251488  memcached的通讯层分析

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值