《绝命书》阅读盗墓笔记在线阅读

提高学生的阅读能力从课外阅读开始_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
&&¥3.00
&&¥3.00
喜欢此文档的还喜欢
提高学生的阅读能力从课外阅读开始
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢memcached 源码阅读笔记 - 博客 - 伯乐在线
& memcached 源码阅读笔记
| 标签: ,
阅读 memcached 最好有 libevent 基础,memcached 是基于 libevent 构建起来的。通由 libevent 提供的事件驱动机制触发 memcached 中的 IO 事件。
个人认为,阅读源码的起初最忌钻牛角尖,如头文件里天花乱坠的结构体到底有什么用。源文件里稀里哗啦的函数是做什么的。刚开始并没必要事无巨细弄清楚头文件每个类型定义的具体用途;很可能那些是不紧要的工具函数,知道他的功能和用法就没他事了。
来看 memcached 内部做了什么事情。memcached 是用 c 语言实现,必须有一个入口函数main(),memcached 的生命从这里开始。
初始化过程
建立并初始化 main_base,即主线程的事件中心,这是 libevent 里面的概念,可以把它理解为事件分发中心。
建立并初始化 memcached 内部容器数据结构。
建立并初始化空闲连接结构体数组。
建立并初始化线程结构数组,指定每个线程的入口函数是worker_libevent(),并创建工作线程。从worder_libevent()的实现来看,工作线程都会调用event_base_loop()进入自己的事件循环。
根据 memcached 配置,开启以下两种服务模式中的一种:
以 UNIX 域套接字的方式接受客户的请求
以 TCP/UDP 套接字的方式接受客户的请求
memcached 有可配置的两种模式: UNIX 域套接字和 TCP/UDP,允许客户端以两种方式向 memcached 发起请求。客户端和服务器在同一个主机上的情况下可以用 UNIX 域套接字,否则可以采用 TCP/UDP 的模式。两种模式是不兼容的。特别的,如果是 UNIX 域套接字或者 TCP 模式,需要建立监听套接字,并在事件中心注册了读事件,回调函数是event_handler(),我们会看到所有的连接都会被注册回调函数是event_handler()。
调用event_base_loop()开启 libevent 的事件循环。到此,memcached 服务器的工作正式进入了工作。如果遇到致命错误或者客户明令结束 memcached,那么才会进入接下来的清理工作。
UNIX 域套接字和 UDP/TCP 工作模式
在初始化过程中介绍了这两种模式,memcached 这么做为的是让其能更加可配置。TCP/UDP 自不用说,UNIX 域套接字有独特的优势:
在同一台主机上进行通信时,是不同主机间通信的两倍
UNIX 域套接口可以在同一台主机上,不同进程之间传递套接字描述符
UNIX 域套接字可以向服务器提供客户的凭证(用户id或者用户组id)
其他关于 UNIX 域套接字优缺点的请参看:
工作线程管理和线程调配方式
在thread_init(),setup_thread()函数的实现中,memcached 的意图是很清楚的。每个线程都有自己独有的连接队列,即 CQ,注意这个连接队列中的对象并不是一个或者多个 memcached 命令,它对应一个客户! 一旦一个客户交给了一个线程,它的余生就属于这个线程了! 线程只要被唤醒就立即进入工作状态,将自己 CQ 队列的任务所有完完成。当然,每一个工作线程都有自己的 libevent 事件中心。
很关键的线索是thread_init()的实现中,每个工作线程都创建了读写管道,所能给我们的提示是: 只要利用 libevent 在工作线程的事件中心注册读管道的读事件,就可以按需唤醒线程,完成工作,很有意思,而setup_thread()的工作正是读管道的读事件被注册到线程的事件中心,回调函数是thread_libevent_process().thread_libevent_process()的工作就是从工作线程自己的 CQ 队列中取出任务执行,而往工作线程工作队列中添加任务的是dispatch_conn_new(),此函数一般由主线程调用。下面是主线程和工作线程的工作流程:
前几天在微博上,看到 @高端小混混 的微博,转发了:
“多任务并行处理的两种方式,一种是将所有的任务用队列存储起来,每个工作者依次去拿一个来处理,直到做完所有的&任务为止。另一种是将任务平均分给工作者,先做完任务的工作者就去别的工作者那里拿一些任务来做,同样直到所有任务做完为止。两种方式的结果如何?根据自己的场景写码验证。”
memcached 所采用的模式就是这里所说的第二种! memcached 的线程分配模式是:一个主线程和多个工作线程。主线程负责初始化和将接收的请求分派给工作线程,工作线程负责接收客户的命令请求和回复客户。
memcached 是做缓存用的,内部肯定有一个容器。回到main()中,调用assoc_init()初始化了容器–hashtable,采用头插法插入新数据,因为头插法是最快的。memcached 只做了一级的索引,即 接下来的就靠 memcmp() 在链表中找数据所在的位置。memcached 容器管理的接口主要在 item.h .c 中.
每个连接都会建立一个连接结构体与之对应。main()中会调用conn_init()建立连接结构体数组。连接结构体 struct conn 记录了连接套接字,读取的数据,将要写入的数据,libevent event 结构体以及所属的线程信息。
当有新的连接时,主线程会被唤醒,主线程选定一个工作线程 thread0,在 thread0 的写管道中写入数据,特别的如果是接受新的连接而不是接受新的数据,写入管道的数据是字符 ‘c’。工作线程因管道中有数据可读被唤醒,thread_libevent_process()被调用,新连接套接字被注册了event_handler()回调函数,这些工作在conn_new()中完成。因此,客户端有命令请求的时候(譬如发起 get key 命令),工作线程都会被触发调用event_handler()。
当出现致命错误或者客户命令结束服务(quit 命令),关于此连接的结构体内部的数据会被释放(譬如曾经读取的数据),但结构体本身不释放,等待下一次使用。如果有需要,连接结构体数组会指数自增。
一个请求的工作流程
memcached 服务一个客户的时候,是怎么一个过程,试着去调试模拟一下。当一个客户向 memcached 发起请求时,主线程会被唤醒,接受请求。接下来的工作在连接管理中有说到。
客户已经与 memcached 服务器建立了连接,客户在终端(黑框框)敲击 get key + 回车键,一个请求包就发出去了。从连接管理中已经了解到所有连接套接字都会被注册回调函数为event_handler(),因此event_handler()会被触发调用。
void event_handler(const int fd,const short which,void *arg) {
c = (conn *)
assert(c != NULL);
c-&which =
/* sanity */
if (fd != c-&sfd) {
if (settings.verbose & 0)
fprintf(stderr,&Catastrophic: event fd doesn't match conn fd!\n&);
conn_close(c);
drive_machine(c);
/* wait for next event */
event_handler()调用了drive_machine().drive_machine()是请求处理的开端,特别的当有新的连接时,listen socket 也是有请求的,所以建立新的连接也会调用drive_machine(),这在连接管理有提到过。下面是drive_machine()函数的骨架:
// 请求的开端。当有新的连接的时候 event_handler() 会调用此函数。
static void drive_machine(conn *c) {
bool stop =
int sfd,flags = 1;
struct sockaddr_
int nreqs = settings.reqs_per_
const char *
assert(c != NULL);
while (!stop) {
// while 能保证一个命令被执行完成或者异常中断(譬如 IO 操作次数超出了一定的限制)
switch(c-&state) {
// 正在连接,还没有 accept
case conn_listening:
// 等待新的命令请求
case conn_waiting:
// 读取数据
case conn_read:
// 尝试解析命令
case conn_parse_cmd :
// 新的命令请求,只是负责转变 conn 的状态
case conn_new_cmd:
// 真正执行命令的地方
case conn_nread:
// 读取所有的数据,抛弃!!! 一般出错的情况下会转换到此状态
case conn_swallow:
// 数据回复
case conn_write:
case conn_mwrite:
// 连接结束。一般出错或者客户显示结束服务的情况下回转换到此状态
case conn_closing:
通过修改连接结构体状态 struct conn.state 执行相应的操作,从而完成一个请求,完成后 stop 会被设置为 true,一个命令只有执行结束(无论结果如何)才会跳出这个循环。我们看到 struct conn 有好多种状态,一个正常执行的命令状态的转换是:
conn_new_cmd-&conn_waiting-&conn_read-&conn_parse_cmd-&conn_nread-&conn_mwrite-&conn_close
这个过程任何一个环节出了问题都会导致状态转变为 conn_close。带着刚开始的问题把从客户连接到一个命令执行结束的过程是怎么样的:
客户connect()后,memcached 服务器主线程被唤醒,接下来的调用链是event_handler()-&drive_machine()被调用,此时主线程对应 conn 状态为 conn_listining,接受请求
dispatch_conn_new(sfd,conn_new_cmd,EV_READ | EV_PERSIST,DATA_BUFFER_SIZE,tcp_transport);
dispatch_conn_new()的工作是往工作线程工作队列中添加任务(前面已经提到过),所以其中一个沉睡的工作线程会被唤醒,thread_libevent_process()会被工作线程调用,注意这些机制都是由 libevent 提供的。
thread_libevent_process()调用conn_new()新建 struct conn 结构体,且状态为 conn_new_cmd,其对应的就是刚才accept()的连接套接字.conn_new()最关键的任务是将刚才接受的套接字在 libevent 中注册一个事件,回调函数是event_handler()。循环继续,状态 conn_new_cmd 下的操作只是只是将 conn 的状态转换为 conn_
循环继续,conn_waiting 状态下的操作只是将 conn 状态转换为 conn_read,循环退出。
此后,如果客户端不请求服务,那么主线程和工作线程都会沉睡,注意这些机制都是由 libevent 提供的。
客户敲击命令「get key」后,工作线程会被唤醒,event_handler()被调用了。看! 又被调用了.event_handler()-&drive_machine(),此时 conn 的状态为 conn_read。conn_read 下的操作就是读数据了,如果读取成功,conn 状态被转换为 conn_parse_cmd。
循环继续,conn_parse_cmd 状态下的操作就是尝试解析命令: 可能是较为简单的命令,就直接回复,状态转换为 conn_close,循环接下去就结束了; 涉及存取操作的请求会导致 conn_parse_cmd 状态转换为 conn_nread。
循环继续,conn_nread 状态下的操作是真正执行存取命令的地方。里面的操作无非是在内存寻找数据项,返回数据。所以接下来的状态 conn_mwrite,它的操作是为客户端回复数据。
状态又回到了 conn_new_cmd 迎接新的请求,直到客户命令结束服务或者发生致命错误。大概就是这么个过程。
memcached 的分布式
memcached 的服务器没有向其他 memcached 服务器收发数据的功能,意即就算部署多个 memcached 服务器,他们之间也没有任何的通信。memcached 所谓的分布式部署也是并非平时所说的分布式。所说的「分布式」是通过创建多个 memcached 服务器节点,在客户端添加缓存请求分发器来实现的。memcached 的更多的时候限制是来自网络 I/O,所以应该尽量减少网络 I/O。
我在 github 上分享了 memcached 的源码剖析注释:
为作者带来更多读者;为读者筛选优质内容;专注IT互联网。
最新评论(期待您也参与评论)
汇集优质的Python技术文章和资源。人生苦短,我用Python!
JavaScript, CSS, HTML5 这里有前端的技术干货!
关注安卓移动开发业界动态,分享技术文章和优秀工具资源。
关注iOS移动开发业界动态,分享技术文章和优秀工具资源。
为作者带来更多读者;为读者筛选优质内容;专注IT互联网。
由数百名译者组成,立志翻译传播优秀的外文技术干货。
一个专门为IT单身男女服务的征婚传播平台。
收录优秀的工具资源,覆盖开发、设计、产品和管理等。
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线博客团队正试图以我们微薄的力量,把优秀的原创/译文分享给读者,做一个小而精的精选博客,为“快餐”添加一些“营养”元素。
欢迎关注更多频道
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选博客文章
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
(加好友请注明来意)
网站使用问题
请在询问或者反馈
& 2015 伯乐在线
赞助云主机, 赞助云存储1.2《墙上的斑点》课件(人教版选修《外国小说欣赏》)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者
评价文档:
&&¥2.00
喜欢此文档的还喜欢
1.2《墙上的斑点》课件(人教版选修《外国小说欣赏》)
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
大小:1.79MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢四级阅读专题
03-30&03-30&03-27&03-09&03-06&02-11&01-30&01-27&01-25&12-22&
英语四级最新推荐
最近,你在工作上花费了太多的时间,甚至将工作带回家.工作直到凌晨,周六,周日你仍埋头
一项最新研究发现,牢固美满的婚姻有助于缓解女性的压力。
英语四级阅读排行
1111111111
1111111111
1111111111
我们也在这里:斯科特 给英国公众的绝命书(一篇阅读笔记)我要的是你们写好的阅读笔记_百度作业帮
拍照搜题,秒出答案
斯科特 给英国公众的绝命书(一篇阅读笔记)我要的是你们写好的阅读笔记
斯科特 给英国公众的绝命书(一篇阅读笔记)我要的是你们写好的阅读笔记
斯科特的爱心和顽强让人们感动,他的爱国之情和在同不可战胜的厄运中搏斗时变得高尚的心灵也让人钦佩,这些都从他的笔记中表现了出来,人们从中真实地感到斯科特的那些品质和他生前不被人了解的地方.看他的画像,那是一个不苟言笑、严肃、生硬的人.他外表冷酷,是一个典型的英国绅士,没有任何突出的地方,也没有什么凡人没有的气质,总之就是一个普通人.他和很多英国人一样忙着出海,是一名海军军官.由于表现得勤奋,且经验丰富,被任命去南极点考察,他发过誓后,就率着队伍出发了.他的结局是悲惨的,但过程是伟大的.人们从他的笔记中认识了一个全新的斯科特,与过去完全相反.他死了,死后被誉为高尚的人.但是,还有那么一些人,被历史的大海给淹没了.他们分量太重,很快沉入了深海,被沙石埋住,被侵蚀掉,被黑暗包住,永远不会被人们发现.他们生前有种种恶名,或一直是平凡的,没人知道,却在活着时,创造了辉煌的事业,给了人类后,自己就悄悄死了,除了他的成果外,他自己就永远消失了,就如没在地球上生活过,像一阵风一样无影无踪了.在斯科特生死不明时,他被批评为指挥失误.各方面,英国的准备都优于挪威方面,却失败了,斯科特的失误,斯科特使这次计划失败了.发现了斯科特的日记后,人们的看法也就变了,人们甚至希望斯科特能再回来.他离自己的基地仅一天半的路程,但是他还是失败了.但同时,他也是幸运了,他死后,人们会了解他,他被后来的人比作人类的群星. 实际上,在无限黑暗里还有更多的群星,但是人们不知道,人们不了解他们,所以,这些星星也就谁也不知道了. 那些书信写得非常感人.死亡在即,信中却没有丝毫悲哀绝望的情意,仿佛信中也渗透着那没有生命的天空下清澈的空气.那些信是写给他认识的人的,也是说给全人类听的;那些信是写给那个时代的,但说的话却是千古永垂的. 他给自己的妻子写信.他提醒她要照看好他的最宝贵的遗产——儿子,他关照她最主要的是不要让儿子懒散.他在完成世界历史上最崇高的业绩之一的最后竟作了这样的自白:“你是知道的,我不得不强迫自己有所追求——因为我总是喜欢懒散.”在他行将死去的时刻,他仍然为自己的这次决定感到光荣而不是感到遗憾.“关于这次远征的一切,我能告诉你什么呢?它比舒舒服服地坐在家里不知要好多少!” 他怀着最诚挚的友情给那几个同他自己一起罹难的伙伴们的妻子和母亲写信,为他们的英勇精神作证.尽管他自己即将死去,他却以坚强的、超人的感情——因为他觉得这样死去是值得纪念的,这样的时刻是伟大的——去安慰那几个伙伴的遗属. 他给他的朋友写信.他谈到自己时非常谦逊,但谈到整个民族时却充满无比的自豪,他说,在这样的时刻,他为自己是这个民族的儿子——一个称得上儿子的人而感到欢欣鼓舞.他写道:“我不知道,我算不算是一个伟大的发现者.但是我们的结局将证明,我们民族还没有丧失那种勇敢精神和忍耐力量.”他在临死时还对朋友作了友好的表白,这是他在一生中由于男性的倔强而没有说出口的话.他在给他的最好的朋友的信中写道:“在我一生中,我还从未遇到过一个像您这样令我钦佩和爱戴的人,可是我却从未向您表示过,您的友谊对我来说意味着什么,因为您有许多可以给我,而我却没有什么可以给您.” 他最后的也是最精彩的一封信是写给他的祖国的.他认为有必要说明,在这场争取英国荣誉的搏斗中他虽然失败了,但却无个人的过错.他一一列举了使他遭到失败的种种意外事件,同时用那种死者特有的无比悲怆的声音,恳切地呼吁所有的英国人不要抛弃他的遗属.他最后想到的仍然不是他的命运.他写的最后一句话讲的不是关于自己的死,而是关于活着的他人:“看在上帝面上,务请照顾我们的家人!”以下便是几页空白的信纸. 参考资料:/question/.html# 回答者: 刘晋玮2008 - 魔法师 四级
5-10 09:43英国绅士,没有任何突出的地方,也没有什么凡人没有的气质,总之就是一个普通人.他和很多英国人一样忙着出海,是一名海军军官.由于表现得勤奋,且经验丰富,被任命去南极点考察,他发过誓后,就率着队伍出发了.他的结局是悲惨的,但过程是伟大的.人们从他的笔记中认识了一个全新的斯科特,与过去完全相反.他死了,死后被誉为高尚的人.但是,还有那么一些人,被历史的大海给淹没了.他们分量太重,很快沉入了深海,被沙石埋住,被侵蚀掉,被黑暗包住,永远不会被人们发现.他们生前有种种恶名,或一直是平凡的,没人知道,却在活着时,创造了辉煌的事业,给了人类后,自己就悄悄死了,除了他的成果外,他自己就永远消失了,就如没在地球上生活过,像一阵风一样无影无踪了.在斯科特生死不明时,他被批评为指挥失误.各方面,英国的准备都优于挪威方面,却失败了,斯科特的失误,斯科特使这次计划失败了.发现了斯科特的日记后,人们的看法也就变了,人们甚至希望斯科特能再回来.他离自己的基地仅一天半的路程,但是他还是失败了.但同时,他也是幸运了,他死后,人们会了解他,他被后来的人比作人类的群星. 实际上,在无限黑暗里还有更多的群星,但是人们不知道,人们不了解他们,所以,这些星星也就谁也不知道了. 回答者:
- 助理 二级
5-10 13:54仅从这封信中就能看出,斯科特是一位勇敢、坚强、伟大的英国科学探险家.他敢于向南极点发出挑战,尽管最后输给了对手,但他终究是赶到了目标.遇到困难,他依然乐观地认为这都是必然遭受到的,同时也竭尽全力去克服.尤其是他率领考察队在返回的路上连续跋涉了两个多月,粮食紧缺,饥寒交迫,行走还得靠人拉雪橇,其艰难程度可想而知.但在最后准备接受死神的审判时,他们依然没有抱怨、哀叹.这种乐观坚强的精神着实令人折服.斯科特同时很热爱祖国,他赞美祖国人民吃苦耐劳,互相帮助,这也都在他身上体现出了.他将与世长辞之时,仍执笔着书,给后人留下了宝贵的精神财富,以他勇敢、坚强、伟大的精神鼓励人们向科学进发、永不放弃. 回答者:
- 试用期 一级
5-10 19:41}

我要回帖

更多关于 藏獒笔记免费阅读 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信