memcached 线程处理模型

memcached 每个处理子线程有一个event结构,各个子线程处理分配给该线程的请求

typedef struct {
    pthread_t thread_id;        /* unique ID of this thread */
    struct event_base *base;    /* libevent handle this thread uses */
    struct event notify_event;  /* listen event for notify pipe */
    int notify_receive_fd;      /* receiving end of notify pipe */
    int notify_send_fd;         /* sending end of notify pipe */
    struct thread_stats stats;  /* Stats generated by this thread */
    struct conn_queue *new_conn_queue; /* queue of new connections to handle */
    cache_t *suffix_cache;      /* suffix cache */
    uint8_t item_lock_type;     /* use fine-grained or global item lock */
} LIBEVENT_THREAD;

1、进程启动时,main调用thread_init()初始化线程数据

for (i = 0; i < nthreads; i++) {
    int fds[2];
    if (pipe(fds)) {
        perror("Can't create notify pipe");
        exit(1);
    }

    //主线程接收到新的连接请求后,把连接请求加入thread的到new_conn_queue队列中,notify_receive_fd用来通知处理线程
    threads[i].notify_receive_fd = fds[0];
    threads[i].notify_send_fd = fds[1];

    setup_thread(&threads[i]);
    /* Reserve three fds for the libevent base, and two for the pipe */
    stats.reserved_fds += 5;
}

2、建立线程
setup_thread()

/* Listen for notifications from other threads */
//设置notify_receive_fd的回调函数thread_libevent_process
//监听notify_receive_fd,接收来自主线程的通知
event_set(&me->notify_event, me->notify_receive_fd,
          EV_READ | EV_PERSIST, thread_libevent_process, me);
event_base_set(me->base, &me->notify_event);

cq_init(me->new_conn_queue);//初始化连接队列

3、启动线程

static void *worker_libevent(void *arg) {
    LIBEVENT_THREAD *me = arg;

    /* Any per-thread setup can happen here; thread_init() will block until
             * all threads have finished initializing.
             */

            /* set an indexable thread-specific memory item for the lock type.
             * this could be unnecessary if we pass the conn *c struct through
             * all item_lock calls...
             */
            me->item_lock_type = ITEM_LOCK_GRANULAR;
            pthread_setspecific(item_lock_type_key, &me->item_lock_type);

            register_thread_initialized();

            event_base_loop(me->base, 0);
            return NULL;
    }

4、当有新的连接到来时,主线程写入管道通知处理线程。处理线程接收到主线程的通知后,调用回调函数thread_libevent_process。
a)从请求队列中取出连接:
item = cq_pop(me->new_conn_queue);
b)分配新连接
conn *c = conn_new(item->sfd, item->init_state, item->event_flags,
item->read_buffer_size, item->transport, me->base);
c)设置回调函数
event_set(&c->event, sfd, event_flags, event_handler, (void *)c);//设置回调函数event_handler

d)把连接注册到线程的base中
event_base_set(base, &c->event);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值