- 博客(47)
- 资源 (9)
- 收藏
- 关注
原创 rocksDB的LRU cache 三两说
先讲单shard的LRU cache,主要有3个数据结构LRUHandle 作为LRU的一个个体元素,其数据结构如下,next,prev是在LRU的双向列表的next和prev,next_hash是在hash_table用来解决拉链地址冲突。key_data[1]被分配了连续的地址,用来存储key值struct LRUHandle { void* value; void (*delet...
2019-12-20 15:30:25
678
原创 cacheline 优化
今天看rockdb的代码, 看到整个程序在分配内存和释放的内存的时候,并不是直接用的malloc 或者 new 等,而是使用cacheline_aligned_alloc,了解了一下相关原理,内存load到缓存的时候 ,是按照cacheline大小load到缓存的,所以进行分配内存的时候,尽量按照cacheline大小进行分配,这样访问一个结构体就是访问一个cacheline,这些细节可以使得程序...
2019-12-20 10:30:28
396
原创 对于RCU的衍生思考-- 设计一个线程安全的链表
只考虑单链表,直接对各种情况进行分析,对于Insert,需要关注的点在于,先要对new_node 进行初始化。且Insert的时候要加锁,意味着同时只有一个元素写链表。void InsertList(ListNode *new_node, ListNode* prev , ListNode *next) { new_node->next = next; wmb(); prev-&g...
2019-05-17 10:51:59
299
原创 对顺序锁的思考
今天读到顺序锁的概念,似乎对之前被问到的锁优化问题,有了一些新的理解,说不定可以用这个来解决。先定义一下顺序锁的数据结构吧.typedef struct { spinlock_t lock; // 用来锁住写,临界区只有一个写 int seq; //版本号控制,后续详解}seq_lock_t;说要顺序锁,可以分为读写两方。那么先来看写的一方是怎么做的?//锁操作如下void pt...
2019-05-16 13:49:47
168
1
原创 c++原子同步
#include <sys/cdefs.h>#include #include <stdio.h>using namespace std;int main(){int v = 10;cout << __sync_fetch_and_add(&v,1) << endl;cout << v << endl;...
2019-05-15 11:52:20
341
原创 zooKeeper和ZAB协议总结一下
zookeeper的主备同步和leader选举是通过ZAB协议来完成的。写一下能够记得更牢一些。因为ZK大多数是读,少部分写,所以读都是读follower。写的是leader数据同步的过程类似于二阶段提交Client 写数据到leader,leader为每一个follower构建队列,异步将写入的数据放到队列里队列里的数据发送proposal给到每一个followerfollower收...
2019-05-10 10:08:15
128
原创 redis skiplist阅读
撸过一遍代码之后,对一些数据结构才能更深的了解读完redis的跳跃表,现在用c++重新实现了插入、查询和删除3个api方法,理解下来跳跃表,主要思路有1. 从上层逐渐到下层搜索,上层步长更大,这样上层迅速定位到一个更接近的点。2. 下层用于精细化查找,速度更慢3. 与有序数组相似,有序数组的查找效率是N,这个为logN主要用途:1. 网络框架中,根据sequenc...
2018-12-11 14:07:10
128
原创 network flow 最大流
好久没写了,最近研究了一下,最大流算法。其实主要的思路,是寻找增广路径,找不到起点到汇点时就没有了。下面写下代码好了。最大流算法能解决的问题,1. 顾明思义,即一组网络上能够容纳的最大流量问题2. 可以解决数学的组合问题。其原理上还是一个规划问题下面的代码是,通过bfs找到一条增广路径。int find_path_bfs(int s, int e){ i...
2018-11-09 15:10:57
467
原创 debug 新方法
直接上代码吧 debug.h 如下#ifndef __COMMON_DEBUG__#define __COMMON_DEBUG__#include <signal.h>typedef int signal_t;typedef void (*SignalHandler)(signal_t sig_no);typedef void (*SignalHandlerConte...
2018-08-07 08:51:13
281
原创 版本控制头文件
#ifndef __VERSION_H__#define __VERSION_H__#define STRING_HELPER(str) #str#define STRING(x) STRING_HELPER(x)#define VERSIO
2017-09-28 09:33:36
312
原创 自己写的线程池, threadpool
这个代码还没有调试过, 不过应该问题不大, 下次用起来就直接用,调一下就好#ifndef __THREAD_POOL_H__#define __THREAD_POOL_H__#include <pthread.h> #include <queue>class CThreadJob;class CWorkerThread {public: CWorkerThread(); v
2017-09-28 09:32:54
409
原创 对TCP状态的新理解
以前一直不明白TCP的四次断连接的意义在哪,通过一段时间实践的领悟大约明白了 1. 首先发起断连接的一方,发送一个FIN信号给被断连接的从方,在C++的代码里表示为close(fd),那么这个连接就进入FIN_WAIT1状态。 2. 被动的一方,在收到断连接之后发送ack给主动断连接的一方,这时候被动方就进入CLOSE_WAIT状态,主动方就进入FIN_WAIT2状态。值得注意的是,这个是协议自
2017-09-08 11:01:24
213
原创 字节对齐
今天写代码,遇到个问题,数据结构是这样的,然后收header的时候,cmd内容怎么都对不了,知道struct c++的字节对齐,这个结构体占16字节。struct PacketHeader { uint16_t magic_num; uint32_t seq_num; uint16_t cmd; uint32_t packet_len;};以后写代码的时候了解一下,
2017-08-09 12:04:35
257
原创 C++ 反射的实现
首先是要写一个类,这个类主要有2个功能,注册类和通过类名获取类实例的功能typedef map<string, void *> class_map;typedef void* (*CreateObject)(void);//声明class ClassFactory{public: void Register(const string &name, CreateObject
2017-07-11 09:21:11
384
原创 上线服务观察
上线一个服务需要观察的点有 1. 服务的内存使用情况是否正常 在做agent的时候,由于后期改了监控的逻辑,导致一部分内存泄漏,内存持续增长。 觉得观察的步骤是在程序上线几个周期,5分钟持续关注,如果一直上涨得思考,一天后也要一直关注5分钟,这时候如果不是很高一般问题不大,不过几天后也要看内存的增长情况,同时看看是否有错误日志。 2. 错误日志是否持续打印。 3. 查看程序
2017-06-05 17:00:06
281
原创 CMakeList 编写和debug release区分
cmake_minimum_required(VERSION 2.6)PROJECT(active_service)EXECUTE_PROCESS(COMMAND git log -1 --pretty=format:%h OUTPUT_VARIABLE version)add_definitions(-DACTIVE_GIT_VERSION=${version})set(CMAKE_CXX_
2017-04-27 16:08:48
7475
原创 signal 进程通信
先看send: 1. 定义信号量函数static void sighandler(int signo){ sigval tid; tid.sival_int = signo; cout << pid <<" " << signo << endl; sigqueue(pid, SIGWINCH, tid); // 发送给接收端信号量和
2017-04-26 08:40:39
442
原创 一种反射机制
今天看dtc代码,有这样的一种实现,感觉还挺巧妙的。 先说过程,再说好处:char *so = ...//读取配置文件,得到so的文件名void* dll = dlopen(so, RTLD_NOW|RTLD_GLOBAL);//打开sochar *fun; //读取配置文件得到,得到方法名typedef uint64_t (*fun_interface)(const char *key,
2017-04-06 20:39:09
315
原创 Http类
废话不多说,以后直接用这个/** cycle.cc** Created on : 2016.12.30* Author : qiulu*/#include "http_helper.h"bool HttpHelper::Init(Config *config){ m_Config = config; if (m_Config->isMember("report_u
2017-03-29 09:56:32
394
原创 小顶堆
废话不多说,直接代码, 以后就用这个:/*author : qiuludate : 2017-03-07*/#ifndef _MIN_HEAP_H#define _MIN_HEAP_H#include<vector>using namespace std;template <class T>class MinHeap{public: MinHeap():m_HeapSize
2017-03-07 16:18:40
349
原创 异步化方案
最近做项目,需要调用的一些服务,但是这个服务本身和主线程没有什么关联,所以这时候我们可以将其异步化,从而提升整体的性能。 然后我是怎么做的呢? 第一步,肯定是要开启线程,初始化mutexpthread_mutex_t locker; pthread_cond_t cond;pthread_t thread;queue<AsynJob *> m_qtransfer; //队列作为缓冲区p
2017-03-02 15:11:17
446
原创 curl 使用范例 c++
1.curl_global_init(CURL_GLOBAL_ALL);m_CurlHandle = curl_easy_init();//初始化环境,构造handle2. struct curl_slist *headers = NULL;headers = curl_slist_append(headers, "Accept: */*");//构造头3. 回调的函数后面再讲curl
2017-02-23 09:29:26
1800
原创 tcpdump
今天读了一些tcpdump的使用方式, 总结一下, 还是用最简单的例子来说吧:sudo tcpdump -i eth0 host 192.168.166.40-i 指定网卡host 表示从host出发到结束的包然后读一下结果15:50:27.113450 IP test.saurfang.jd.com.47462 > 192.168.166.40.websm: Flags [P.], seq 2
2017-02-22 16:38:50
317
原创 Nginx事件模块小结
这两天着重看nginx事件模块的处理,这一部分跟网络框架比较大。跟现在工作内容相关性也比较大,总结一下它在这方面的处理方式,下次写代码的时候可以用一下。得到了2点启发: 1. 防止epoll惊群,可以采用锁的方式处理,但是不能等epoll响应的事件处理完再释放锁,这样锁的占用时间会比较长,从而使得其他的进程无法epoll wait,拖慢效率。可以先把事件加入连接池,释放锁,然后再处理。 2.
2017-01-11 10:50:36
297
原创 agent TCP read
这两天解除了网络模型,踩了一些坑, 现在写一点惨痛教训。 TCP 才read的时候,可能有这几种情况1. 返回值>0,这种情况又分为2中情况 1.1 返回值==想要读到的size,这种情况意味着这次读工作良好, 且读到了想要的byte数,在处理的时候,不要标记该连接的状态,继续下次read 1.2 返回值 < 想要读到的size,
2016-12-05 14:19:12
482
原创 Nginx 内存池管理
Nginx内存池的设计十分巧妙, 可以研究一下, 以后再写代码的时候可以用上。其具体分配的每个内存块的结构如下图。那么怎么构造出这样的结构呢? 看下下面的数据结构再说。它有两个最为重要的数据结构,如下: 其中ngx_pool_s即所谓的内存池, 他数据的具体细节可以参考注释:typedef struct { u_char *last;//表示当前可以写的位置,当
2016-10-13 10:34:32
360
转载 手把手教你使用Git
转载自:http://my.oschina.net/gsbhz/blog/337719Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不 需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上 改了文件A,这时,你们两之间只需把各自的修改推送给对方
2016-10-12 16:01:31
263
原创 HAproxy 和Agent的内存管理
今天读了agent的内存管理,其优势在于不用频繁地申请和释放内存,从而消耗时间,但是也有劣势在于内存只会增加,不会下降。那么下面来解读一下它的实现。一: 首先从基本架构来说,可以看到,在内存里面其实是由链表连接的pool。 每个pool包含了一个链表和size,链表内的每个项表示每个内存块,每个内存块的大小由size决定,。可以看下面的数据结构。一些重要的数据项已经用注释说明。struct po
2016-10-11 11:10:21
572
3
原创 Linux 挂在windows 目录小技巧
首先要检查在linux的目录受否存在如下的文件,如果不存在,需要安装/sbin/mount.cifs在windows 下建立共享文件夹 linux下执行以下语句sudo mount -t cifs //192.168.142.1/buffer/ ~/windows/ -o username=choulu若想要开机自动挂在则需要在/etc/fstab中添加如下语句//192.168.1
2016-09-27 16:22:30
1364
原创 优雅地reload
今天做项目,借鉴nginx的代码,做了一个优雅的重启,在重启过程中不断服务,保持系统可用性。具体的过程如下 1. 注册信号量 程序在运行过程中,当kill -s SIGUSR1 pid的shell语句执行时,程序接收到该信号,执行sig_reload函数, 将全局变量reload = 1static void sig_reload(int signo){ reload = 1;}s
2016-09-21 17:20:44
373
原创 Nginx事件模块init
首先在nginx里面最重的是下述三个模块ngx_events_module,ngx_event_core_module,ngx_epoll_module,ngx_events_module这个模块属于core_module在程序起来的时候就init, 它的commands成员只有一个,也就是说只关注配置文件中events这一标签。static ngx_command_t ngx_events_
2016-09-14 17:49:18
365
原创 c++ 定时器实现
1. setitimer方法nginx 实现, 在这段代码中,定义了itimerval的数据结构,并设置这个数据结构的值,从而定时器的间隔时间,settimer的函数第一个参数表示经过timer就会触发sigalarm事件, 然后注册了信号sigalarm的事件,从而触发定时器signal(SIGALRM, printMsg); void printMsg(int num) { print
2016-09-12 15:27:26
3038
原创 Epoll 小结(Nginx)
1. 数据结构//表示一个要监听的事件//其中events表示监听的标志位 EPOLLIN EPOLLOUT//表示被触发后的datastruct epoll_event{ uint32_t events; epoll_data_t data;}//其中只有ptr数据结构比较重要typedef union epoll_data{ void *ptr; i
2016-09-07 16:14:10
420
原创 c++ mysql
1. 数据库连接MYSQL *mysql_real_connect(MYSQL *mysql, //在调用函数前,需定义并初始化这个变量 const char *host,//想要连接的数据库ip地址 const char *user, //连接的数据库的用户名
2016-08-25 15:14:17
359
原创 nginx worker进程
1. ioctl一些参数#include <sys/ioctl.h>ioctl(int fd, int request, ...)fcntl(int fd, int request, ...)// fd 为需要对哪个文件描述符进行操作// 对fd进行操作的request//... 为参数在nginx 的创建worker 进程时有以下应用场景 1.将描述符设为非阻塞ioctl(s, FI
2016-08-16 16:40:01
818
原创 C++查看环境变量
#include<stdio.h>#include<stdlib.h>extern char **environ;int main(){ int i = 0 ; for(i = 0 ; environ[i] ;i++) { printf("%s\n", environ[i]); }
2016-08-15 10:10:16
1969
原创 iptable
1. 查看规则 iptable -L -n2. 添加规则iptables -A OUTPUT -d 192.168.144.124 -p tcp --dport 20289 -j REJECT 添加一个阻止到192.168.144.124:20289 的数据流iptables -A OUTPUT -s 192.168.144.124 -p tcp --sport 20289 -j
2016-08-02 09:37:15
494
原创 HAProxy Tips
1 size=(size+align+1)&-align //size 是align的整数倍因为size&-align等于比n*align . n*align< size. 假设align的最低位1为第x位,那么x-1,x-2,1位都为0,&操作会让这些位置0,从而保证size&-align 可以是n*align。
2016-07-27 16:53:25
257
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人