- 博客(111)
- 收藏
- 关注
原创 lua5.1.3源码分析之GC
一、概述lua实现了对象间的引用管理,在对象不被其他对象应用时,自动释放对象的内存。二、lua对象类型和数据结构1、哪些类型需要GClua的基本类型包括nil、boolean、number、lightuserdata、string、table、function、userdata、thread九种数据类型,另外还有proto、upvalue两种内部类型。其中string、table、function、userdata、thread、proto、upvalue是引用类型,可以被其他多个对象同时引用,需
2022-02-28 02:17:06
588
原创 Debian11镜像源
腾讯云镜像站deb https://mirrors.tencent.com/debian/ bullseye main non-free contribdeb-src https://mirrors.tencent.com/debian/ bullseye main non-free contribdeb https://mirrors.tencent.com/debian-security/ bullseye-security maindeb-src https://mirrors.tencent
2022-02-23 10:56:29
2336
原创 Lua5.1.5源码分析之table实现
一、概述table实现了一个hash表功能,能否方便按key-value来存储数据。lua的table表功能非常强大,key、value的类型可以是number、boolean、string、table、userdata等。二、实现数据结构table的数据结构主要包括一个哈希表和一个数组。具体的结构定义如下图:查询和插入流程查询和插入会判定key的类型,按不同的类型有不同的处理nil:返回nilint:值小于Table.array数组的长度,返回array里的值,否则当成dou
2022-02-17 04:00:57
993
原创 Lua5.1.5源码分析之string实现
一、概述string是Lua的一种数据类型,它不同于普通的基本类型,为了节约内存,多个相同的字符串会共用一个,因而需要管理string的引用情况,从而实现在不被用时,能正确GC。二、实现细节1、string数据类型定义string在Lua运行时里的数据结构是TString。具体的定义如下。如上图,TString可以认为是一个GCObject的派生类(实际不是,只是有GCObject相同的数据成员)。主要记录了string的hash值,长度,字符串值等。3、字符串管理存储结构所有的短字符
2022-02-15 03:36:58
494
原创 Lua5.3.6源码分析之string实现
一、概述string是Lua的一种数据类型,它不同于普通的基本类型,为了节约内存,多个相同的短字符串会共用一个,因而需要管理string的引用情况,从而实现在不被用时,能正确GC。二、实现细节1、字符串分类Lua为了节省内存,Lua的字符串分为短字符串和长字符串。短字符串: 长度小于等于40为短字符串。相同字符的短字符串是共用同一个的。长字符串: 长度大于40为长字符串。相同的两个长字符串是两个独立的字符串。2、string数据类型定义string在Lua运行时里的数据结构是TString。
2022-02-13 02:46:43
963
原创 mongodb复制集配置
我们配置一主一从一仲裁的mongo复制集。1、创建目录cd /var/lib/mongodbmkdir mainmkdir slavemkdir arbiter2、创建主服务配置vi /etc/mongodb/main.conf内容如下:dbpath=/var/lib/mongodb/mainlogpath=/var/log/mongodb/main.loglogappend=trueport=27018noauth=trueoplogSize=2048replSet=Test
2021-02-12 02:02:21
279
原创 libevent源码分析之时间管理和定时器
一、概述libevent提供了高性能定时器的功能,方便执行延迟回调逻辑。二、基本实现原理在添加事件监听的时候,可以不指定fd和监听的事件,指定超时的时间,实现定时器功能。定时器的底层实现包含两个部分:最小堆:按事件的超时时间构造,超时时间最早的在堆顶。通用超时队列:这个可以个性化设置每个队列的超时时间,添加事件时时间相同的放到同一个队列里,在最小堆里只添加一个队列首部的事件到最小堆。能避免大量事件都放到最小堆,导致最小堆添加、删除时性能变差的问题。三、最小堆实现最小堆的实现采用了典型的数
2021-01-25 01:32:37
653
原创 libevent源码分析之IO多路复用
一、IO多路复用概念IO多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞,挂起线程,直到阻塞超时。二、libevent的IO多路复用应用libevent支持多种IO多路复用机制,保障了跨平台和性能。支持的IO多路复用包括:机制平台selectunix、linuxwin32selectwinpollunix、linuxepollunix、linuxkqu
2021-01-24 18:50:12
405
1
原创 libevent源码分析之Reactor模式
一、概述libevent使用了Reactor模式,实现了高效的事件驱动机制。二、Reactor定义1、Reactor是一种事件驱动机制。应用程序不是主动的调用某个系统API完成处理,Reactor逆置了事件处理流程,应用程序注册回调函数到Reactor上,如果相应的事件(比如读、写、错误)发生,Reactor将回调应用程序注册的接口。2、Reactor结构五个关键的参与者:描述符(handle):由操作系统提供,用来识别每一个事件,如socket描述符、文件描述符等。同步事件分离器(demul
2021-01-23 18:03:44
485
1
原创 libevent源码分析之目录结构说明
一、概述1、目录分类:头文件:分为提供给外部使用的头文件和内部使用的头文件。reactor框架:包括事件的定义、事件的监听和触发、定时器功能。io多路复用封装:包括select、poll、epoll、iocp、kqueue等。socket、收发缓冲区封装:网络缓冲区evbuffer实现,bufferevent管理了socket和网络缓冲区。基础数据结构:链表、最小堆、红黑树、哈希表等。dns、http库:基于libevent实现。其他:辅助功能函数、日志。2、具体文件说明1)
2021-01-17 07:47:20
241
原创 libevent源码分析之概述
一、libevent特性libevent是一个轻量级的开源高性能网络库,应用广泛。比如大家比较熟悉的memcached、chrome等。Libevent具有以下优点:事件驱动,高性能轻量级,专注于网络跨平台,在主流操作系统上都能运行。可扩展性,考虑各种使用的情景,提供良好的性能。方便可靠,只需要调用少量的libevent接口就能使用很好地使用libevent库。二、libevent主要功能libevent采用了Reactor反应堆模式。具备reactor模式响应快、编程简单、可扩展、
2021-01-11 03:09:49
409
原创 网络缓冲区的4种实现方法
一、概述网络缓冲区用于缓冲待发送的数据或接收了待处理的数据,发送缓冲区可以积累一定量的数据再发送,接收缓冲区可以积累一定量的数据,解决粘包导致的没有收到完整的数据包,缓冲起来等包数据完整了再提交给业务逻辑处理。二、实现方案根据我的经验,这里将介绍四种实现机制,包括单块连续内存缓冲,环形缓冲,环形分块缓冲,链表分块缓冲。1. 单块连续内存缓冲单块连续缓冲是最简单地实现机制。这种方案采取一块连续的内存来作为缓冲区,随着数据的写入和读取,有效数据块会逐渐往后移动,在合适的时机把整块有效数据移动到头部。如
2020-11-06 01:15:04
3315
原创 硬件性能总结
CPU:频率3GHZ,一个指令周期耗时,0.3纳秒。CPU Cache L1:耗时1纳秒,相当于3个指令周期。CPU Cahe L2:耗时5纳秒,相当于15个指令周期。CPU Cahe L3:耗时13纳秒,相当于40个指令周期。DDR3:频率1.333GHZ,每秒最大内存读取速度8GB/s。读取一次耗时60纳秒,约180个指令周期(实际会一次取多个数据缓存到CPU Cache里),耗时高不是由于DDR3的速度慢,而是内存到CPU的线路传输耗时长。DDR4:频率2.666GHZ,每秒最大内存读取速
2020-08-19 01:48:14
231
原创 redis有序集合相关命令
一、概要redis的有序集合可以用来支持超大规模的排序,底层采用了跳表或ZIP_LIST来实现。二、相关接口示例127.0.0.1:6379> ZADD test 100 a(integer) 1127.0.0.1:6379> ZADD test 200 b(integer) 1127.0.0.1:6379> ZADD test 300 c(integer) 1127.0.0.1:6379> ZINCRBY test 200 b"400"127.0.0.1:63
2020-07-27 00:46:06
110
原创 Redis集合相关命令
一、概要redis中值可以是一个集合,集合的底层实现是INT_SET或HASH_TABLE。redis的集合命令包括往集合里添加、删除元素,对集合做差集、交集、并集操作。二、代码示例127.0.0.1:6379> HSET test a 1(integer) 1127.0.0.1:6379> HGET test a"1"127.0.0.1:6379> HSET test a 1(integer) 1127.0.0.1:6379> HSET test b 2(int
2020-07-26 14:26:45
173
原创 Redis哈希表相关指令
一、概要redis里值可以是一个哈希表,哈希表底层实现可以是一个HASH_TABLE或ZIP_LIST。redis命令可以创建、删除哈希表,单插入、多插入、单删除、多删除哈希表的键值对,也可以获取哈希表、哈希表的所有键、哈希表的所有值。二、代码示例127.0.0.1:6379> HSET test a 1(integer) 1127.0.0.1:6379> HGET test a"1"127.0.0.1:6379> HSET test a 1(integer) 1127.
2020-07-26 14:09:58
174
原创 Redis列表相关指令
一、概要Redis列表采用LINKEDLIST或ZIPLIST实现,支持从左右两端压入或弹出元素,也支持查找和区间缩减、按值删除操作,但不支持按索引删除或按范围删除。二、使用示例127.0.0.1:6379> RPUSH list 1 2 3 4 5(integer) 5127.0.0.1:6379> RPOP list"5"127.0.0.1:6379> LPUSH list 0 -1(integer) 6127.0.0.1:6379> LPOP list"-1
2020-07-26 01:34:24
109
原创 Redis字符串相关命令
一、概要Redis中值为字符串时,可以对字符串做追加、范围修改、范围获取、当成数组做加减等。二、使用示例127.0.0.1:6379> SET test 1OK127.0.0.1:6379> INCR test(integer) 2127.0.0.1:6379> INCRBY test 10(integer) 12127.0.0.1:6379> DECR test(integer) 11127.0.0.1:6379> DECRBY test 5(int
2020-07-26 00:32:16
103
原创 unique_ptr功能、源码解析、使用范例
一、概述unique_ptr用于管理对象,实现对象的自动释放,它不能被拷贝或赋值,保证了指针只被它管理,提供了接口转移拥有权。二、使用示例#pragma once#include <memory>#include <string>#include <iostream>using namespace std;class PtrClass{private: string s;public: PtrClass(string s) { this-&
2020-07-18 01:24:51
749
原创 unique_lock使用示例、源码分析
一、概要unique_lock实现了lock_guard类似的功能,但unique_lock保证了只有一个unique_lock拥有mutex,同时提供了转移拥有权的接口。二、代码示例#pragma once#include <mutex>#include <thread>#include <iostream>using namespace std;class UniqueLockTest{private: mutex _mutex; int co
2020-07-18 00:06:34
471
3
原创 lock_guard原理解析
一、说明lock_guard用来包装Mutex,实现Mutex的自动锁定和解锁。能保证锁定过程中逻辑异常也能自动解锁。二、windows下的源码template<class _Mutex> class lock_guard<_Mutex> { // specialization for a single mutexpublic: typedef _Mutex mutex_type; explicit lock_guard(_Mutex& _Mtx) //传的
2020-07-16 00:21:01
1656
原创 promise使用示例
一、概要promise实现跨线程设置和获取值,底层使用了mutex来保证设置值的原子性,通过future实现了跨线程等待获取结果。二、代码#pragma once#include <future>#include <thread>#include <chrono>#include <iostream>using namespace std;class PromiseTest{private: promise<int> p;
2020-07-14 00:06:25
209
原创 C++future、async使用示例
一、概述async可以启动一个线程(不保证)来处理逻辑,async调用后悔返回一个future,通过future可以用来等待处理完成或查看处理进度。二、代码#pragma once#include <future>#include <chrono>using namespace std;class AsyncTest{private: int count = 0; int maxLoop = 2000000000;public: int process()
2020-07-13 00:57:06
602
原创 SpinLock源码
一、概要spinLock的基本原理是如果发现其他人锁着,就一直循环,知道其他人解锁后,再上锁。一般SpinLock适用于锁的时间很短的情况,通过不断判定是否可以加锁,避免适用Mutex这类操作系统锁带来不能锁定时的上下文切换。二、实现源码#pragma once#include <atomic>#include <thread>using namespace std;class SpinLock{private: atomic<bool> _flag;
2020-07-12 01:29:39
297
1
原创 结构体、类、虚函数的内存大小
一、概要C++里结构体和类除了默认访问不一样外,其他基本是一样的,结构体可以有函数甚至是虚函数,所以内存大小上也是一样。但内存的大小不是简单地把所有成员变量的大小加起来就可以,需要考虑对齐、虚函数等,具体看测试的结果。二、测试代码#pragma once#include "stdafx.h"#include <stdio.h>class MemoryClassAlign0{ char a;};class MemoryClassAlign1{ char a; char c
2020-07-12 00:40:33
1245
原创 Atomic、Mutex性能测试
一、结论1、Atomic、Mutex相对于不加锁有较大的性能差别。2、Mutex的性能开销是Atomic的两倍左右。二、测试代码#pragma once#include <atomic>#include <thread>#include <chrono>using namespace std;class AtomicTest{private: atomic<long long> atomicCount=0; long long nor
2020-07-10 00:32:19
684
原创 shared_ptr实现机制
一、概述shared_ptr实现了引用计数的功能,在引用计数为0时,自动delete掉管理的对象。二、实现要点shared_ptr需要实现构造对象以及赋值时的计数。shared_ptr需要实现自身销毁时的计数减少。需要实现计数为0时自动销毁管理的对象。需要实现std::move语义。要处理多线程下的计数问题。三、shared_ptr的简单实现源码#pragma once#include <memory>#include <atomic>using name
2020-07-08 01:25:15
763
原创 Enet实现原理
一、Enet简介在UDP(用户数据报协议)的基础上提供一个相对薄,简单且健壮的网络通信层,它的主要功能是可选的可靠,按顺序传送数据包。Enet省略了某些更高级别的网络功能,例如身份验证,服务发现,加密或其他特定于应用程序的类似任务,因此该库保持灵活,可移植且易于嵌入。二、为啥需要EnetTCP不支持多信道TCP需要用户自己处理粘包问题UDP不支持排序,连接管理,带宽资源管理,数据包的大小有限制Enet实现了基于单一UDP,具有UDP和TCP等价功能,但比同时集成UDP和TCP更干净的统一
2020-07-02 20:50:08
7514
原创 CAP原则
CAP原则指的是在分布式系统中,CAP(Consistency一致性、Avaiable可用性、Partition tolerance分区容错性),最多满足其中两个,不可能三个都满足。一致性: 更新操作成功后,所有数据备份在同一时刻完全相同。可用性: 每一个请求能在有限时间内返回结果(不保证正确)。分区容忍性: 由于网络故障导致部分节点不可用时,能保证对外提供一致性或可用性的服务。对于分布式系统,一般需要保证P,需要能容忍分区间的网络故障。如果保证一致性,就需要等待分区恢复,失去了可用性。如果保证可用
2020-06-21 23:04:01
218
原创 网络术语汇总
链路层:MTU(Maximum Transfer Unit) 最大传输单元以太网中的一般为1500字节网络层:TTL(Time To Live)限制了IP包被路由器丢弃之前允许通过的跳数,最大255。传输层:MSS(Maximum Segment Size) 最大报文段大小TCP的报文段中的数据部分的最大字节数,MTU减去IPv4包头和TCP的包头,一般MSS=1500-20-20 = 1460字节RTT(Round-Trip Time)从发送端发送数据开始,到发送端收到来自接收
2020-05-24 23:51:37
478
原创 IO多路复用之select详解
一、select用户select是 I/O多路复用系统函数,用来等待文件描述符状态的改变。它会一直阻塞,直到一个或多个文件描述符集合称为就绪态或者指定一个超时时间。它不适合文件数量庞大、I/0流量频繁的时候,它会随着fd的数量增大性能下降明显。二、接口windows定义:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout)linux定义:
2020-05-22 01:55:04
1379
原创 c++的virtual和override作用
一、概述c++的virtual提供了运行时的多态,是的可以用基类的指针调用子类对象的函数,通过override可以强制要求基类有对应的虚函数。二、测试代码#pragma once#include <stdio.h>class Base{public: void A_1() { printf("Base::A_1\n"); }; virtual void A...
2020-04-13 23:06:23
6375
1
原创 32位进程地址空间
对于一个进程,其空间分布如下图所示:保留区: 位于地址空间的最低部分(大概100来M),未赋予物理地址。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。会放些动态链接库等。程序段: 代码段也称正文段或文本段,通常用于存放程序执行代码(即CPU执行的机器指令)。初始化过的数据(Data Segment): 用于存放程序中已初始化且初值不为0的全局变量和静态局部变...
2020-03-23 00:42:47
1481
原创 事务的ACID说明
原子性(针对一个数据的改变来说)是一个独立的操作单元,要么全部是,要么全部不是的原则单位性操作。一致性(针对一个事务的结果来说)一个事务可以封装状态改变。事务始终保证系统处于一致的状态。隔离性(针对不同事务来说)交错使用时也能提供一致性。隔离让我们隐藏来自外部世界未提交的状态变化。持久性(针对结果的保持来说)事务执行成功以后,该事务对数据库所作的更改便是持久的保存在数据...
2020-03-10 19:19:45
94
原创 gdb调试方法
一、具体方法attach一个进程gdb attach pid查看线程信息info threadsId Target Id Frame1 Thread 0x7f5ccfd39740 (LWP 24823) “mono” 0x00007f5ccf202528 in p...
2020-03-10 15:33:55
799
原创 设计模式实践之抽象工厂
一、定义抽象工厂:提供一个创建一系列相关或相互依赖的接口,而无需指定他们具体的类。二、分析1、模式关键词创建一系列相关对象,延迟到具体的工程类来确定实际创建的对象2、优点分离了具体的类,使用时用抽象工厂类来创建对象。易于交换产品系列。有利于产品一致性,才用的是同系列的对象。3、缺点难以支撑新种类的产品,新加一种产品需要修改所有工厂类。三、实践#pragma on...
2020-03-09 00:36:04
117
原创 C++vector、unorderd_map,C# List Dictionary扩容策略
C++vector0 1 2 3 4 6 9 13 19 28 42 63 94 141 211 316 474 711 1066 1599 2398 3597 5395 8092 12138 18207 27310 40965 61447 92170 138255 207382 311073 466609 699913 1049869 1574803 2362204 3543306 5314...
2020-03-08 19:25:34
424
原创 Python基本语法示例
#coding=utf-8import sys #str = input()#print(str)def fun(base): a = base for i in range(1,10): a += i while a<120 : a+=a; if a >100: break; ...
2020-03-08 17:39:48
166
原创 redis为什么采用跳表而不是红黑树
在做范围查找的时候,平衡树比skiplist操作要复杂。平衡树需要以中序遍历的顺序继续寻找其它不超过大值的节点。skiplist进行范围查找非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现。平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而skiplist的插入和删除只需要修改相邻节点的指针,操作简单又快速。skiplist需要更少的指针内存。平均每个节点包含1...
2020-03-08 16:13:56
854
原创 Redis知识点
一、Redis数据类型:String:最大512M,内部采用了sdsHash:哈希表,List:链表,ziplist或linkedlistSet:集合,内使用intset或hashtableZSet:有序集合,内部使用ziplist或skiplist二、Redis持久化RDB:全存,会 fork当前进程,采用写时复制技术避免耗时过高,把进程数据生成 RDB 文件;AOF:把操作存到...
2020-03-08 15:10:22
84
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人