memcached 线程处理模型

来源:互联网 发布:java使用postmethod 编辑:程序博客网 时间:2024/06/15 14:11

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);

0 0