博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
memcached线程模型
阅读量:6252 次
发布时间:2019-06-22

本文共 3468 字,大约阅读时间需要 11 分钟。

直接上图:

memcached使用多线程模型,一个master线程,多个worker线程,master和worker通过管道实现通信。

每个worker线程有一个队列,队列元素为CQ_ITEM。

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 */    logger *l;                  /* logger buffer */    void *lru_bump_buf;         /* async LRU bump buffer */} LIBEVENT_THREAD;/* An item in the connection queue. */typedef struct conn_queue_item CQ_ITEM;struct conn_queue_item {    int               sfd;    enum conn_states  init_state;    int               event_flags;    int               read_buffer_size;    enum network_transport     transport;    conn *c;    CQ_ITEM          *next;};/* A connection queue. */typedef struct conn_queue CQ;struct conn_queue {    CQ_ITEM *head;    CQ_ITEM *tail;    pthread_mutex_t lock;};

memcached使用libevent实现事件监听,master和worker各有一个event_base。

起初,master负责监听连接的到来,worker线程负责监听管道的读事件。

当有一个连接到来,master线程accept该连接,并将conn_fd封装成一个CQ_ITEM对象放入一个worker线程的队列中,同时向管道写入数据触发管道读事件。

对应worker线程执行管道读事件的回调函数thread_libevent_process:

/* * Processes an incoming "handle a new connection" item. This is called when * input arrives on the libevent wakeup pipe. */static void thread_libevent_process(int fd, short which, void *arg) {    LIBEVENT_THREAD *me = arg;    CQ_ITEM *item;    char buf[1];    unsigned int timeout_fd;    if (read(fd, buf, 1) != 1) {        if (settings.verbose > 0)            fprintf(stderr, "Can't read from libevent pipe\n");        return;    }    switch (buf[0]) {    case 'c':        item = cq_pop(me->new_conn_queue);        if (NULL != item) {            conn *c = conn_new(item->sfd, item->init_state, item->event_flags,                               item->read_buffer_size, item->transport,                               me->base);            if (c == NULL) {                if (IS_UDP(item->transport)) {                    fprintf(stderr, "Can't listen for events on UDP socket\n");                    exit(1);                } else {                    if (settings.verbose > 0) {                        fprintf(stderr, "Can't listen for events on fd %d\n",                            item->sfd);                    }                    close(item->sfd);                }            } else {                c->thread = me;            }            cqi_free(item);        }        break;    case 'r':        item = cq_pop(me->new_conn_queue);        if (NULL != item) {            conn_worker_readd(item->c);            cqi_free(item);        }        break;    /* we were told to pause and report in */    case 'p':        register_thread_initialized();        break;    /* a client socket timed out */    case 't':        if (read(fd, &timeout_fd, sizeof(timeout_fd)) != sizeof(timeout_fd)) {            if (settings.verbose > 0)                fprintf(stderr, "Can't read timeout fd from libevent pipe\n");            return;        }        conn_close_idle(conns[timeout_fd]);        break;    }}

在conn_new中,将conn_fd的读事件添加进自己的event_base中。

至此,worker线程开始监听连接上的I/O事件。

 

参考资料:

转载于:https://www.cnblogs.com/gattaca/p/6929361.html

你可能感兴趣的文章
oracle解密后台包,oracle9i加密解密包用法
查看>>
oracle数据库nmon日志在哪,oracle技术之nmon使用说明
查看>>
oracle10g实例修改表空间,oracle10g建表空间和修改oracle字符和删除表空间和用户(加 标注)...
查看>>
linux命令语法规则,Linux系统tar命令怎么使用语法规则
查看>>
linux查看服务器静态路由配置,配置Linux静态路由和配置IP
查看>>
linux应用程序使用时钟中断,Linux时钟中断(2.6.23)(三)
查看>>
win7读取linux硬盘序列号,Windows 下获取硬盘序列号
查看>>
linux音频设备接口,OSS--跨平台的音频接口简介
查看>>
华为网卡linux驱动安装,Linux Nvidia显卡驱动安装
查看>>
linux sql撤销,取消请求的sql语句
查看>>
c语言学习 二维指针,二维数组和指针(C语言)
查看>>
图像压缩算法构造最优解c语言,C语言与程序设计第12章递归.ppt
查看>>
c语言飞机源代码,C语言写的飞机源码
查看>>
C语言 如果某个数大于10 归零,C:当指针实际指向某个东西时,函数继续接收归零指针(示例代码)...
查看>>
c c 语言项目实战 pdf,[计算机]C实战项目.pdf
查看>>
linux中solr创建core,Solr6.6 创建core
查看>>
android的边框阴影,android 自定义shape 带阴影边框效果
查看>>
android centos 的编码,Centos 安装 android sdk
查看>>
反编译android 状态栏沉浸,手把手教你傻瓜式开启状态栏沉浸模式
查看>>
android l job scheduler api,Android JobScheduler API
查看>>