- 博客(116)
- 收藏
- 关注
原创 半同步/半反应堆线程池实现
半同步/半异步反应堆线程池:主线程监听listen socket和接收到的所有连接socket,当有客户端请求任务时,将任务对象插入到工作任务对象中;等待在任务队列上的工作线程通过竞争来取得任务对象并处理之。其中的工作任务队列完成了主线程与工作线程之间的解耦,但是由于同一客户连接的任务请求可能由不同的线程来处理,所以这要求所有的客户请求是无状态的。具体细节,尽在代码中:
2015-07-02 22:58:05
1425
原创 半同步/半异步并发模式进程池实现
半同步/半异步并发模式:父进程监听到新的客户端连接请求后,以通信管道通知进程池中的某一子进程:“嘿,有新的客户连接来了,你去accept,然后处理下!”,从而避免在进程间传递文件描述符。这种模式中,一个客户连接上的所有任务始终有同一个进程来处理。具体细节,尽在代码中:
2015-07-02 22:20:35
1143
原创 编程语言明日之星——go语言
正如Go语言之父Rob Pike自己所说:”Go的目标是解放程序员!“《Go语言之父谈Go:大道至简》“没有最好,只有更好”,对于编程语言来说,Golang正是我们苦苦寻觅的更好者。(以下内容来自[[转载记录]使用Go语言一段时间的感受]|)(http://studygolang.com/articles/3204) 有一段时间没更新了。最近在忙一个Server+Client的项目,Client是
2015-06-08 10:57:31
8479
原创 C++primer(第四版)复习笔记—第三篇: 类和数据抽象
数据抽象:是指定义数据和函数成员的能力; 封装:是指从常规访问中保护类成员的能力。 接口:成员函数定义了类的接口。通过将定义类所用到的数据和成员函数设置维为private来封装类。第十二章: 类1、 构造函数的初始化式只在构造函数的定义中而不是声明中指出。 2、 使用构造函数的初始化列表与在构造函数体中对类的成员变量进行赋值的区别:本质就在于前者是对变量进行初始化,而后者是对变量进行赋值。
2015-04-10 16:39:47
846
原创 C++primer(第四版)复习笔记—第二篇:容器和算法
第九章:顺序容器1、 顺序容器的元素按其位置存储和访问,其元素的排列元素的值无关,而是按其加入的顺序存储。 关联容器。其元素按键(key)来排序。2、 标准库定义了三种顺序容器: vector/list /dequeue。 标准库还提供了三种容器适配器: 根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型。顺序容器: vector:支持快速随机访问 List :支持快速插入和删除 Deque:双端对列顺序容器适配器: stack:后进先出(
2015-04-07 09:43:46
878
原创 逆序输出链表节点
注意:递归的本质是栈#include <list>#include <stack>#include <iostream>using namespace std;//递归实现逆序输出链表节点void PringListReversingly( list<int> &L, list<int>::iterator &it){ if(it!=L.end()) { list<int>
2015-04-05 00:28:27
486
原创 C++primer(第四版)复习笔记—第一篇:基本语言
本次复习一方面是为了查漏补缺,另一方面也是更加深入的理解C++的思想精髓。在此记录复习中记录的各知识细节及理解,以便后续温故之用。第一张:快速入门 1. for语句: for(初始化语句;条件测试语句;条件修改表达式){ 语句体 } 。执行顺序:初始化语句在最开始执行一次,然后执行条件测试语句,若成立则执行语句体;然后再执行条件修改表达式,再执行条件测试语句,成立则继续,反之则退出for语句。
2015-04-02 16:46:24
1115
原创 红黑树—Red Black Tree
红黑树是具有以下五条性质的二叉查找树:1、每个结点要么是红的要么是黑的。 2、根结点是黑的。 3、每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的。 4、如果一个结点是红的,那么它的两个儿子都是黑的。 5、 对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。 正是由于红黑树的以上五个性质,使得其高度最多是2log(N+1),从而保证红黑树的查找、插入、删除的时间复杂度最坏为O(log n)。 在插入、删除过程中最关键的就是时刻保证RBT的五个性质
2015-03-28 21:47:10
1151
原创 单源最短路径问题——Dijkstra算法
解决单源最短路径问题的一般方法是Dijkstra算法,该算法是贪婪算法的典型应用。其基本思想是对有向赋权图以开始顶点出发,逐层外扩(即广度优先搜索),以寻找当前最短路径。 1、从顶点V1为出发顶点,其距离dv1=0,为最小值,因此选择处理v1,将v1设为已知,与V1连接的顶点为v2、v4。其距离均小于当前dv4 和dv2的无穷大,因此更新:dv4=1,dv2=2; 2、选择当前距离最小未知顶
2015-03-27 16:15:07
1103
原创 最小生成树(MST)——Kruskal算法
最小生成树Kruskal算法是在处理一个森林——树的集合。开始时将图的每个顶点看做一棵树(集合),然后采用贪婪策略,每次从所有边中依次选出(Find)权值最小的边,当改边的两个端点不在同一集合时,则将终点所在集合与起点集合合并(Union),直到依次处理完所有的边,算法终止,此时所有的顶点在一个树中,即为最小生成树。
2015-03-25 10:23:39
902
原创 最小生成树(MST)——Prim算法
一个无向图的最小生成树由该无向图的那些连接相互连接的顶点的边构成的树,且使得该树的所有边的总权值和最小。最小生成树问题在实际生活中也广泛存在,例如:要在一个村庄修建一条公路,连通到村里的每户人家,选择怎么的路线铺设道路使得总的距离最短(造价最低)。 最小生成树算法之一:Prim算法,将整个顶点集合分为两个子集U、V,U中存放已经在生成树中的顶点,V中存放未在生成树中的顶点。算法核心的每一步将从U、V中各选一顶点,使得边的权值w(u,v)最小,然后将该顶点v从V中移到U中,如此直到集合V为空,即完成。该过程
2015-03-24 23:11:53
1844
原创 二叉堆(Binary_Heap)
二叉堆满足其结构性,和堆序性。结构性:要求为完全二叉树,即除树的最底层外,树被完全填满,且底层的元素从左向右填充。堆序性:即在堆中要求,对任意元素X,X的父节点的关键字小等于X的关键字,如此得到最小堆。同理可得最大堆。 由于堆序性,因此二叉堆也常称为实现优先队列(Priority Queue)。 在对二叉堆进行操作时需要始终保持其结构性和堆序性。可用数组来实现二叉堆。数组中的元素关系为:i位置上的节点,其左儿子在2i上,右节点在2i+1上,父节点在i/2(取整)上。用数组代替树结构,从而不用包含指针操作
2015-03-23 10:44:15
950
原创 I/O复用——聊天室程序
本文主要是为熟悉Linux下网络编程,实现一个简单的网络聊天室程序。 以Poll实现I/O复用技术来同时处理网络连接和用户输入,实现多个用户同时在线群聊。其中客户端实现两个功能:一:从标准输入读入用户数据,并将用户数据发送到服务器;二:接收服务器发送的数据,并在标准输出打印。 服务端功能为:接收客户端数据,并将客户数据发送到登录到该服务端的所有客户端(除数据发送的客户端外)。
2015-03-20 19:32:31
843
原创 平衡二叉树(AVLTree)
平衡二叉树(AVLTree)是指带平衡条件的二叉查找树。AVLTree要求每个节点的左子树和右子树的高度之差最多为1。当因为插入或删除操作导致AVLTree不满足该平衡条件时就需要进行调整操作,包括单旋转和双旋转操作。也正是因为需要时刻保持树的平衡条件,从而使得AVLTree的插入和删除操作较为复杂。
2015-03-20 10:26:59
867
原创 The Google File System——论文详解
单一Master节点:如何避免单一的Msaster节点成为系统性能瓶颈:1、客户端只向Master请求元数据信息,并不通过Master节点进行chunk数据读写,具体的数据读写操作由ChunkServer直接负责。 2、客户端在向Master请求某chunk元数据时,Master会一次返回包括该chunk紧接之后的几个chunk信息,有效减少客户端的请求次数。客户端读取数据流程如下:
2015-02-04 10:42:32
6349
原创 《大规模分布式存储系统》——基础篇
分布式存储系统按照所存储的数据对象不同,分为四类:分布式文件系统(存储图片、音频、视频等非结构化的Blob对象、定长块以及大文件等)、分布式表格系统(存储关系较为复杂的半结构化数据)、分布式键值系统(存储关系简单的半结构化数据)和分布式数据库(存储结构化数据)等。
2015-01-30 23:09:08
2463
原创 分布式缓存系统Memcached(十四)——总结
到此关于memcached的主要分析就即将告一段落了。最近通过对LevelDB、Redis以及Memcached等存储系统的学习理解,对大规模存储系统的基本框架原理和实现有了基本的理解。对此也越发兴趣浓厚,接下来需要的是去研读更多这方面的技术书籍,充分利用在校的最后这段时光。在分析memcached的过程中参考了大量存储方面的技术博客文章,正是在此开放的环境帮助下,自己才能走得更好更远。在此列出一些自认为不错的资料:缓存设计的一些思考:http://www.nosqlnotes.net/archives
2015-01-29 11:13:49
979
3
原创 分布式缓存系统Memcached(十三)——基本配置与命令
memcached的客户端使用TCP连接同memcached进行交互,memcached服务器监听指定的端口(默认端口是11211)。Client连接到memcached服务器,发送指令,获取数据,然后关闭连接。通常没有必要发送任何命令来关闭某个会话。客户端可以在任何时候关闭不需要的连接。然而,通常鼓励客户端缓存这些连接,因为memcached服务器本身就被设计成为一个可以支持成百上千个连接的服务器,而客户端缓存了连接后,就可以避免重复的建立连接的开销。memcached协议中包含两部分数据,文本行和非
2015-01-28 10:58:31
894
原创 分布式缓存系统Memcached(十二)——CAS协议
Memcached在1.2.4版本后新增了CAS(Check and Set)协议,主要用于并发控制:memcached中同一个item同时被多个线程(多个客户端)更改的并发问题。CAS协议最本质的东西——版本号,即将每个item都关联一个全局唯一的编号,从而利用该唯一的编号来判断item数据在某个线程操作期间有无被其他的线程所更改(每次更改版本号都会改变,因此可作为判断的标识)。
2015-01-28 10:28:19
792
原创 分布式缓存系统Memcached(十一)——状态机之SET、GET命令
1.listening:这个状态是主线程的默认状态,它只有这一个状态:负责监听socket,接收客户连接,将连接socket派发给工作线程。2.conn_new_cmd:每个工作线程的接收到新连接的初始状态,为处理该连接socket准系列准备工作:如清空读写buf等。3.conn_waiting:当读缓冲区无数据可以处理时,工作线进入等待状态:在event_base中注册读事件,然后状态机暂停,挂起当前connection(函数退出,回调函数的attachment会记录这个connection),等待有
2015-01-27 09:55:19
1350
原创 分布式缓存系统Memcached(十)——状态机之网络数据读取与解析
主线程将接收的连接socket分发给了某工作线程,然后工作线程从任务队列中取出该连接socket的CQ_ITEM,开始处理该连接的所有业务逻辑。这个过程也就是上图中的第一个状态conn_listening。 而工作线程首先进入的状态就是conn_new_cmd,即为这个新的连接做一些准备工作,如清理该连接conn结构的读缓冲区等。
2015-01-26 11:27:57
1131
原创 分布式缓存系统Memcached(九)——状态机之socket连接与派发
Memcached主线程中监听socket注册事件和工作线程中连接socket注册事件的回调函数都是event_handler,且event_handler的核心部分都是一个有限状态机:drive_machine。因此接下来将对该状态机具体的业务处理进行深入的剖析。 memcached将每个socket都封装为一个conn结构体,该结构体包含了比如socket的文件描述符sfd、注册事件event、连接状态结构体conn_states,等等诸多信息字段,其中的状态结构:conn_states中包含了该so
2015-01-25 14:51:26
1385
原创 分布式缓存系统Memcached(八)——主线程之main函数
memcached主线程:创建监听socket、注册监听socket的libevent事件、启动主线程的libevent事件循环,就是接下来的内容了。 其中主要调用的函数是server_sockets,该函数从配置参数setting.inner字符串中依次提取出一个ip或者一个hostname(一个hostname可能有多个ip),然后传给函数server_socket函数处理之。server_socket函数负责完成创建socket,绑定到端口,监听socket,并将该监听socket对应的conn结构
2015-01-22 12:00:40
659
原创 分布式缓存系统Memcached(七)——半同步/半异步模式
在前面工作线程初始化的分析中讲到Memcached采用典型的Master_Worker模式,也即半同步/半异步的高效网络并发模式。其中主线程(异步线程)负责接收客户端连接,然后分发给工作线程,具体由工作线程完成客户端的求情任务。在memcached中,主线程负责监听所有socket上的事件,当socket上有可读事件发生,即新的客户连接求情到来,主线程就接受之得到新的连接socket,并将该连
2015-01-21 21:52:34
962
原创 分布式缓存系统Memcached(六)——slab和item的主要操作
上节在分析slab内存管理机制时分析Memcached整个Item存储系统的初始化过程slabs_init()函数:分配slabclass数组空间,到最后将各slab划分为各种级别大小的空闲item并挂载到对应大小slab的空闲链表slots上。本节将继续分析对slab和item的主要操作过程。slab机制中所采用的LRU算法:在memcached运行过程中,要把一个item调入内存,但内
2015-01-19 21:36:26
788
原创 分布式缓存系统Memcached(五)——内存管理机制
在前面slab数据存储部分分析了Memecached中记录数据的具体存储机制,从中可以看到所采用的内存管理机制——slab内存管理,这也正是linux所采用的内存高效管理机制,对于Memchached这样的内存cache服务器,内存高效管理是其最重要的任务之一。Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。Jeff 的
2015-01-19 11:55:33
1109
原创 分布式缓存系统Memcached(三)——哈希表操作
memcached 中有两张hash 表,一个是“主hash 表”(primary_hashtable),另外一个是“原hash 表”(old_hashtable)。一般情况下都在主表中接受操作,在插入新item时判断是否需要进行扩;每次操作的时候,先会检测表是否正处于扩展(expanding)状态,如果是,则原表中进行操作,当扩容完成在转移到主表中进行操作。 在扩容时,采取逐步迁移策略:即每次只
2015-01-18 18:25:11
770
原创 分布式缓存系统 Memcached(二)——数据存储slab与hashtable
缓存数据以item为基本单元,以双链表形式存放在对应级别大小的slabclass结构的chunk中。同时该item还存放在链式hashtable中bucket中,用于提供快速查找的索引。首先是理解缓存的基本数据单元item结构:typedef struct _stritem { struct _stritem *next; //在slab中的双链表后向指针 str
2014-11-20 20:13:20
859
转载 字符串匹配 KMP算法
字符串匹配是计算机的基本任务之一。举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一。它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth。 这种算法不太容易理
2014-11-12 09:14:05
427
原创 Redis源码分析(二十二)——CRC循环冗余校验
字节型算法的一般描述为:本字节的CRC码,等于上一字节CRC码的低8位左移8位,与 上一字节CRC右移8位(即上以字节的高8位)同本字节异或后所得的CRC码 异或。 其中“上一字节CRC右移8位(即上以字节的高8位)同本字节异或后所得的CRC码” 该CRC码通过查表得到,其查表索引为:上一字节CRC右移8位(即上以字节的高8位)同本字节异或 值。CRC码表,为根据字节的二进制表示 以标
2014-11-04 16:12:32
842
原创 Counting-the-number-of-set-bits-in-an-integer
判断一个整数表示为二进制数时,二进制位为1的数目基本思想:设整数X,则X&(X-1):即把X的二进制表示的最右边的1设为0,因此循环二进制1的数目的次数即能使的X变为全0,而循环的次数即为其中1的数目。另外一个结论:判断正整数X是否为2的N次方注意以上的逆命题不成立。
2014-10-31 17:15:35
927
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人