直接上图:

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[];
unsigned int timeout_fd; if (read(fd, buf, ) != ) {
if (settings.verbose > )
fprintf(stderr, "Can't read from libevent pipe\n");
return;
} switch (buf[]) {
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();
} else {
if (settings.verbose > ) {
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 > )
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事件。

参考资料:

Memcached源码分析之线程模型

memcached线程模型的更多相关文章

  1. Memcached源码分析之线程模型

    作者:Calix 一)模型分析 memcached到底是如何处理我们的网络连接的? memcached通过epoll(使用libevent,下面具体再讲)实现异步的服务器,但仍然使用多线程,主要有两种 ...

  2. 2.redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?

    作者:中华石杉 面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的 ...

  3. redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?

    1.redis和memcached有什么区别? 这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧 1)Redis支持服务器端的数据操作:Redis相比Memcache ...

  4. redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发?

    redis 和 memcached 有啥区别? redis 支持复杂的数据结构 redis 相比 memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作.如果需要缓存能够支持更复杂的结构 ...

  5. Redis 和 Memcached 有什么区别?Redis 的线程模型是什么?为什么单线程的 Redis 比多线程的 Memcached 效率要高得多?

    面试题 redis 和 memcached 有什么区别?redis 的线程模型是什么?为什么 redis 单线程却能支撑高并发? 面试官心理分析 这个是问 redis 的时候,最基本的问题吧,redi ...

  6. redis的线程模型是什么?

    1.面试题 redis和memcached有什么区别? redis的线程模型是什么? 为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发) ...

  7. Java NIO学习与记录(六): NIO线程模型

    NIO线程模型 上一篇说的是基于操作系统的IO处理模型,那么这一篇来介绍下服务器端基于IO模型和自身线程的处理方式. 一.传统阻塞IO模型下的线程处理模式 这种处理模型是基于阻塞IO进行的,上一篇讲过 ...

  8. 关于redis的几件小事(二)redis线程模型

    1.memcached和redis有什么区别? (1)Redis支持服务器端的数据操作 redis和memcached相比,redis拥有更多的 数据结构并且支持更丰富的数据操作 ,通常在memcac ...

  9. 《【面试突击】— Redis篇》-- Redis的线程模型了解吗?为啥单线程效率还这么高?

    能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis的线程模型了解吗?为啥单线程效率还这 ...

随机推荐

  1. 一、VMware Workstation 15中文破解版 下载与安装(附密钥)

    下载地址: 下载地址VMware Workstation Pro 15.5.0 Build 14665864https://download3.vmware.com/software/wkst/fil ...

  2. AJ学IOS 之小知识之xcode6自动提示图片插件 KSImageNamed的安装

    AJ分享,必须精品 一:首先看效果 KSImageNamed是让XCode能预览项目中图片的插件 很牛逼,据说写这个插件的牛人在日本~ 主要针对imageNamed:方法 效果如图: 安装: 首先需要 ...

  3. Android内存优化—dumpsys meminfo详解

    原创置顶 不死鸟JGC 最后发布于2018-12-24 14:19:28 阅读数 3960 收藏展开dumpsys 介绍Dumpsys用户系统诊断,它运行在设备上,并提供系统服务状态信息 命令格式: ...

  4. 不使用tomcat,仅适用javaSE手写服务器--模拟登陆

    1.搭建框架 我们只是简单模拟,框架简单分三个模块 a,服务器端server包 b,servlet,根据不同的请求url,利用反射生产对应的servlet c,IO工具包,用来关闭IO流 d,编写we ...

  5. LeetCode466. Count The Repetitions

    题目链接 传送门 题意 定义一个特殊的串, 现在给出串S1和S2的参数, 问: S2最多可以多少个连接起来扔是S1的子序列, 求出这个最大值 解题思路 注意s1与S1的区别, 可以去看题目描述, 预处 ...

  6. sqlilab less15-17

    less15 试了很多符号,页面根本不显示别的信息,猜测为盲注 可是怎么检测闭合? 万能密码登录 最终试出来'闭合 uname=1' or 1=1 # 接下来就要工具跑 less16 同上用万能密码试 ...

  7. JavaScript--'data-'的用法(1)

    HTML5为我们提供了一个强大的功能,前段也也能实现后台数据库的效果,例如data-xxx <a href="#myModal" data-industry_id=" ...

  8. SVN部署(Centos7,Ubuntu)

    SVN 简介 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Sub ...

  9. 一些软件的 Basic Auth 行为

    一个 WBEM 在2003年的bug I'm trying to access the WBEM service of the CIMOM on the ESX Server 3i and all m ...

  10. MySQL系列(二)

    查看\创建\使用\删除 数据库 用户管理及授权实战 局域网远程连接法 查看\创建\使用\删除\清空\修改 数据库表(是否可空,默认值,主键,自增,外键) 表内容的增删改查 where条件.通配符_%. ...