memcached连接管理

memcached是一个基于libevent的实现

在主线程创建了一个

main_base = event_init();
...
event_base_loop(main_base, 0)

用于监听连接
他还创建了N个工作线程,用于完成具体的业务
每个工作线程也是event_base_loop的,每个线程处理若干个连接。这个连接时主线程的main_base在accept后接入的

在thread_init(settings.num_threads, main_base)里对主线程和工作线程进行一些初始化工作

dispatcher_thread.base = main_base;
dispatcher_thread.thread_id = pthread_self();
全局变量dispatcher_thread记录了主线程的
threads[i]记录的是工作线程的一些信息

pipe(fds)
...
threads[i].notify_receive_fd = fds[0];
threads[i].notify_send_fd = fds[1];
只是主线程和某个工作线程通信的管道

thread_init里调的setup_thread(&threads[i])完成工作线程的libevent的相关初始化

me->base = event_init();
可知,工作线程也有自己的事件循环

event_set(&me->notify_event, me->notify_receive_fd,
              EV_READ | EV_PERSIST, thread_libevent_process, me);

可知,工作线程监听了发往自己的管道信息,只监听读事件,EV_PERSIST保证没有读完会继续读,这里基本就是主线程给工作线程发

me->new_conn_queue = malloc(sizeof(struct conn_queue));

知,工作线程管理了自己的连接队列

初始化完线程后,就开始创建工作者线程。

create_worker(worker_libevent, &threads[i])

worker_libevent是线程函数
在worker_libevent里event_base_loop(me->base, 0)知,work线程开始自己的事件循环。
刚开始时,只有notify_receive_fd这个管道在work线程上


接下来通过server_sockets->server_socket函数创建监听套接字,可以创建unix域,tcp或udp套接字
在server_socket里
error= getaddrinfo(interface, port_buf, &hints, &ai);
...
for (next= ai; next; next= next->ai_next)
{
...
}

只在多网卡下,对每个网口都要监听

conn_new(sfd, conn_listening,EV_READ | EV_PERSIST, 1,transport, main_base)

将监听端口绑在main_base上,就是主线程上的


最后event_base_loop(main_base, 0)开始主线程的事件循环。


事件回调函数event_handler是监听和服务的都用该函数,里面调了drive_machine(c);
很明显是一个状态机,
一个新的连接接入是到这里

case conn_listening:
这里

dispatch_conn_new(sfd, conn_new_cmd, EV_READ | EV_PERSIST, DATA_BUFFER_SIZE, tcp_transport)

将新连接分配到一个work线程上去。

dispatch_conn_new里先是选取一个

CQ_ITEM *item = cqi_new();
...
LIBEVENT_THREAD *thread = threads + tid;

然后将新的连接push入线程的新连接队列里

cq_push(thread->new_conn_queue, item);
最后通过管道向该线程发送一个通知
write(thread->notify_send_fd, "", 1)
work线程在thread_libevent_process里处理管道来的通知
只读了一个字节,表示处理一个连接,如有多个连接,下次循环会继续触发来处理连接
read(fd, buf, 1)
通过cq_pop(me->new_conn_queue)弹出新连接,然后通过conn_new函数把连接绑定到work线程上
conn_new(item->sfd, item->init_state, item->event_flags,
                           item->read_buffer_size, item->transport, me->base)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值