自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(220)
  • 资源 (2)
  • 收藏
  • 关注

原创 lua的GC

关于lua的gc云风大佬在系列文章中讲得很清楚,这里做一下简单的记录。

2024-06-19 20:16:19 1181

原创 关于lua源代码中的EXTRA_STACK宏

经过查看代码发现,p3可能是栈上的数据,luaD_checkstack中可能会调用luaD_reallocstack导致p3不可用。但是用AddressSanitizer工具测试发现,在执行源码自带的trace-globals.lua时,所以luaD_checkstack要放到后面执行。我看到这里就想,干嘛不提前。会报使用已free内存。

2024-06-01 23:23:57 285

原创 lua字符串模式匹配

string.gmatch (s, pattern)中,如果s的开头是’^'字符,不会被当成行首标志,而是被当成一个普通字符。不会输出任何内容,而。会输出^hello。

2024-05-31 16:53:55 339

原创 lua函数执行和虚拟机指令

特别的看一下数据栈的处理,在编译时已确定每个lua函数执行过程中数据栈的最大大小,将ci->top/L->top直接设为最大值,[L->base, L->top)就做为lua指令的“寄存器空间”使用,访问寄存器就是以下标访问base数组。寄存器空间不会很大,但常量数组可能会很大,而B、C的大小有限,如果B或C需要引用的常量地址超出了表示范围,在指令生成阶段,则首先会生成指令将常量装载到寄存器,然后再将B或C改为使用该寄存器地址。不等的情况,跳转到第5条指令,将ra设置为0,此时c为1,会跳过第6条指令。

2024-05-24 22:14:46 1123

原创 lua的数据类型,lua_State,函数调用,协程

stack,stack_last],[base_ci,last_ci]分别是数据栈数组和调用栈数组,stacksize,size_ci分别是两个数组的大小,在需要的时候它们会进行增长。lua_State的top就是正在调用的函数的堆栈的位置啊。lua_call,lua_pcall都可以调lua或c函数,需要准备好函数在栈上。正在调用的函数一定存在于数据栈上,由func引用正在调用的函数对象。ci是当前正在调用的函数的运行状态,base是该函数的栈底指针。luaD_pcall,oldtop是干嘛用的。

2024-05-07 00:00:00 442

原创 使用lua时一个愚蠢的错误

调luaL_openlibs(L)之前栈是空的,lua_call(L, 1, 0)也没在栈上留东西,而所以栈上只有一个值,从栈顶栈底取数据都一样,但lib->func(L)却在栈上遗留了数据。pmain里再去掉luaL_openlibs(L),所以也理解了为什么它用lua_cpcall包了一层pmain,而不是直接调。因为我瞎改了一些代码,最初怀疑是不是调用过程出问题了,栈让我改坏了。但最后却发现问题出在。之前看luaL_openlibs(),感觉直接调打开库的函数好像也没差别,所以将。

2024-04-28 20:00:00 295

原创 lua的字符串和Table类型实现

不是的,刚创建的空表数组部分长度为0,哈希表也为空,插入新元素时,如果key是数字但不在[1,sizearray]范围内,会往哈希表里插,如果发现哈希表没有空闲节点,便会执行rehash(),rehash()会依据一定规则(computesizes()函数,调整数组部分的大小使其利用率不小于50%),重新设置数组和哈希表的大小。为了减少空表的维护成本,定义了一个不可改写的全局空哈希表dummynode,当以大小0初始化或resize哈希表时,node域指向这个dummy节点,此时lsizenode也为0。

2024-04-16 12:51:45 920

原创 CentOS 6.5安装配置SVN服务器

​项目要用SVN来管理,所以需要给服务器安装SVN服务器端。这里仅使用svn://协议来访问SVN服务器,不启用sasl。客户端系统都是Windows,使用起来很简单,这里就不用说了。本文仅针对1.6.11版本。在1.7.14版本上测试时,发现创建的用户无效,客户端checkout时不提示输入用户名,指定用户名也没用,只能使用匿名登录,不知道为什么。

2024-02-26 00:02:29 964

原创 c++的map的内存布局

最后end()指向的是_M_header,其数据部分正好从_M_node_count的位置开始,it->first正好是_M_node_count的位置,it->second则是p的低4字节。有一个指针偶尔会置成0xffffffff,大佬查了几天发现是由于对map的end迭代器进行了错误操作导致的。_Rb_tree_key_compare里有一个_Compare类型的成员变量,std::less没有成员变量,如果使用默认的内存分配器,_Node_allocator里没有成员变量,不占空间。

2024-01-06 20:09:30 693

原创 一个出现异常CLOSE_WAIT连接的问题

listen的端口触发读事件,epoll_wait返回后,accept返回失败,连接已经建立,但没与文件描述符关联。正常情况对端主动关闭的话,我方进入CLOSE_WAIT状态。

2023-12-03 11:13:59 177

原创 一个没正常处理tcp对端关闭的bug

以及其他搜索结果,如果没通过SO_LINGER选项改变close的默认行为,调用close关闭socket时,会关闭两个方向的数据流。写方向上,内核会尝试将发送缓冲区的数据发送,之后发送FIN包结束连接,这个过程中,往套接字写入数据都会返回异常;最近使用自研的http client时发现一个问题,对端在发送响应数据之后立即调用close关闭了连接,我这没有调用到响应的回调,而是调用到了连接关闭的回调。有问题的接收代码如下,问题在于recv返回0时,没有处理已经收到的数据就直接关闭socket。

2023-11-25 11:31:41 559

原创 游戏视野计算

游戏地图是矩形的,将矩形分割成一个个紧邻的大小相等的方形格子,地图中每个对象必然归属于一个格子,每个格子维护了在这个格子里的所有对象。假设地图中所有格子共有row行,column列,那左下角格子的坐标是(0,0),右上角格子的坐标是(column-1,row-1)。每个格子周围的格子与其的偏移量都是相同的,可以先算出周围所有格子的偏移量来,确定某个格子后就可以快速计算出周围所有格子的坐标了。因为对象是用格子管理的,可以先搜集其所在格子周围的格子,然后再判断这些格子里的对象与之的距离是不是在视野距离内。

2023-11-24 20:30:00 289

原创 关于tcp发送成功但对端无法接收情况的思考

客户端在调用send函数或其他函数发送数据时,只是把数据拷贝到socket缓冲区,即可返回成功,但在系统把缓冲区数据经过协议栈、网卡发送到网络上时,服务器正好关闭了连接,就会出现客户端以为发送成功了,但服务器并没有接收到,有些请求就丢失了。所以尝试复用http连接,请求的时候在头部添加Connection:Keep-alive,对端支持,但会在一定时常或一定请求次数后关闭该连接。为什么有些即时聊天软件用udp,是不是也有一点这种考虑,反正即使用tcp,应用层也要做消息确认和超时重传,直接用udp得了。

2023-11-11 11:24:32 1587

原创 页表和cache

当我们访问0x40地址时,依然索引到cache中第0行cache line,由于此时cache line中存储的是地址0x00地址对应的数据,所以此时依然会cache缺失。1个tag对应1个cache line,所以offset位不需要考虑,对比tag的时候已经定位到具体的行了,index位也是固定的了,所以tag只需要记录除offset和index外的位,该例中是32-3-3=26位。别名问题是因为虚拟地址和物理地址多对一导致的,只要物理地址相同的虚拟地址,也在相同的cache地址中就不会有问题。

2023-11-10 23:03:53 1185

原创 突破防火墙的一种方法

当Linux防火墙阻止来自某个ip的数据时,它应该是根据ip数据报里“源IP地址”字段取得的对方ip吧,那对方就不能通过篡改“源IP地址”来绕过防火墙吗?NAT模式下的路由器就修改了这个字段。看一下tcp三次握手的过程,对于服务器端来说,它只要收到了正确的SYN和ACK就算是建立起了连接,所以攻击者可以猜测服务器返回的seq号,总有概率能猜对。但这样的话,攻击者是收不到服务器返回的数据的,对于tcp来说怎么建立连接呢?

2023-11-02 22:33:03 232

原创 Item-Based Recommendations with Hadoop

Mahout在MapReduce上实现了Item-Based Collaborative Filtering,这里我尝试运行一下。 1. 安装Hadoop 2. 从下载Mahout并解压 3. 准备数据 下载1 Million MovieLens Dataset,解压得到ratings.dat,用sed 's/::\([0-9]\{1,\}\)::\([0-9]\{1\}\)::[0-9]\

2023-09-11 21:59:07 1157 1

原创 lua源码学习:解释器和内嵌库

以前游戏里用到过lua,主要是做配置,所以专门看过《lua程序设计》第二版。后面用lua实现了一个功能,大概几千行代码,当时感觉到写起来方便,调试维护确实不易。听说lua只有2万行代码,便实现了主流动态语言的大部分功能,于是想学习一下。最近开始看了一点lua(5.1.4版本)的源代码,主要是lua解释器和内嵌库(不含debug库和string库的模式匹配)。

2023-07-31 11:11:01 399

原创 游戏商品限购支付的实现

另外为减少这种意外,可以让de的订单超时时间戳减2秒,同时给client的超时时间也减2秒,只要从de发出消息到gs处理消息能在2秒内完成就不会有问题,但带来的另一个问题是,超时后2秒内玩家下单都会失败。流程3中给sdk仅发送orderid,没有productid是不够的,考虑这样一种情况,首先生成了商品A的orderid,但用户不付款,然后购买商品B的时候在流程3中填入了商品A的orderid,如果de不校验productid,商品B就占用了商品A的名额。de(delivery)分别连接gs和sdk。

2023-04-17 23:38:40 156

原创 无锁栈的一种实现方式

可能有问题的地方在于I的old_head->next,可以维护一个原子变量计数器,进入I之前加1,离开I后减1,当计数器值不为0时,就把要删除的指针存起来,当计数器为0时,就可以把当前的old_head以及之前暂存的指针一起删除掉了。考虑到每个线程最多只能占用着一个old_head,可以记下每个线程占用着的指针,当想要释放一个指针时,看一下是否有其他线程在占用这个指针,如果没有的话,就可以释放掉。上面的计数方法,粒度有点大,处于I处的线程,可能拿到的不是同样的指针,但会导致所有的待删除指针都无法释放。

2023-04-14 22:54:11 413

原创 简单理解c++11内存序

现代计算机为了加快执行效率,自动的包含了很多的优化。内存模型简单来说是一种契约,开发者利用这个契约完成数据的同步以避免竞争条件,系统(包括编译器,操作系统,处理器)保证执行的逻辑符合契约。c++11有6个内存序选项可应用于原子类型的操作:memory_order_relaxed、memory_order_consume、memory_order_acquire、memory_order_release、memory_order_acq_rel、memory_order_seq_cst。

2023-04-02 23:49:07 755

原创 关于条件变量wait操作中锁的作用

编译成功的话会在lib目录下生成libgmock.a,libgmock_main.a,libgtest.a,libgtest_main.a,头文件在include/gtest下,如果想要安装到系统目录,用root用户执行make install,会将头文件拷贝到/usr/local/include/gtest,将库文件拷贝到/usr/local/lib。,push的时候也可先分配内存,加锁后只需调用shared_ptr的移动构造,虚节点中的数据是未初值化的shared_ptr。这篇文章,解决了我的疑惑。

2023-02-25 22:23:01 696

原创 fnmatch和glob模式匹配

fnmatch、glob、wordexp都是GNU C Library第10章模式匹配中的一部分,该章还包括正则表达式匹配,详细参见。有时候需要一些简单的模式匹配,正则有点杀鸡用牛刀的意思,可以考虑The GNU C Library提供的fnmatch函数。开头的字符串,除非显式指定,如果同时设置了FNM_PATHNAME,上述特殊处理还适用于字符串中。如果匹配成功返回0,如果没有匹配返回FNM_NOMATCH,如果有错误返回其他非零值。):匹配被中括号包围的任一字符,括号间不可为空,例如。

2023-01-15 22:03:34 504

原创 关于pthread_rwlock_t读写锁产生死锁的情况

此时pthread_rwlock_rdlock和pthread_rwlock_wrlock会返回EDEADLK,表示产生了死锁。这段代码看着可能很傻,但如果将写锁和读锁放到两个函数里,一个函数调用另一个函数,就比较容易发生了。所以加锁的时候要判断下返回值,如果是EDEADLK,可以直接终止程序。一个线程持有着(读或者写)锁,又去加(该锁的)写锁,可能会死锁。一个线程持有着写锁,又去加(该锁的)读锁,可能会死锁。

2022-12-30 00:08:06 1063

原创 安装配置vscode

因为硬盘老化,远程Linux服务器越来越慢。同在该机器的一同事用vscode开发,使用的clangd扩展CPU经常跑到很高,我怀疑机器变慢与clangd频繁使用硬盘有些关系。我也换成vscode好了,费时操作放在后台运行,并不会影响前端界面。

2022-11-17 11:35:40 3929 5

原创 有序整数序列的压缩方法

转换的数字缺了个1,强迫症受不了,于是把所有负数的编码减去个2就可以了,然后发现负数的新编码的高7位和补码的低7位正好相反。是整数的内存表示,也就是补码,正数的补码就是它本身,负数的补码中会有很多前导1,用上面的方法会占用多个字节,所以只适用于无符号数。这种编码方式冗余度较高,每个字节都可以根据它的高位的若干比特确定它在整个二进制表示中的位置(比如是首个字节还是非首个字节),即使字节流中丢一些字节,也能定位出下个字符的起始字节。提出了Roaring Bitmap,表现比WAH,Concise更优秀,

2022-09-21 18:19:13 1310

原创 dropbear:一个小巧的ssh server

Dropbear is a relatively small SSH server and client,可运行于类Unix系统上,官网是 Dropbear,同时在 github 上。这里主要关注dropbear的服务端功能。centos 7环境启动dropbear服务端一些编译选项修改authorized_keys文件不想用~/.ssh/authorized_keys的话,可以通过改代码实现,在svr-authpubkey.c中的checkpubkey函数和checkpubkeyperms函

2022-06-15 22:53:24 2267

原创 tcp端口转发

PortProxy 是一个Windows本地端口转发管理工具,使用了Windows内置命令netsh。现假定host A可建立到host B的ssh连接。既可以使host A上端口P1的数据,通过A–>B的ssh隧道,到达host C的端口P2,这称为本地端口转发。也可以使host B上端口P1的数据,通过B–>A的ssh隧道,到达host C的端口P2,这称为远程端口转发。举例:想让服务器10.6.8.12将2022端口上的请求转发至22端口,这样也能通过2022端口ssh连接了。不加-g,会在

2022-06-10 18:12:27 2997

原创 std::tuple的实现

发现一个在gdb中打印tuple信息的脚本,为了看懂,了解了tuple的实现,发现gcc的实现很需要技巧。

2022-03-28 15:14:15 1089

原创 理解无栈协程

c++20加入了协程,为了性能实现的是无栈协程。有栈协程与无栈协程和有栈协程与无栈协程对协程的两种实现做了介绍,简单来说有栈协程是可以中断并恢复执行的subroutine,无栈协程是状态机。使用 C 语言实现协程中介绍的这个无栈协程实现可以帮助更好的理解为什么说无栈协程是状态机。coroutine.h只用三个宏(这里有简化)就实现了一个不可重入的无栈协程:#define scrBegin static int scrLine=0; switch(scrLine) { case 0:#defi

2022-02-26 19:20:58 2390

原创 造https client轮子的记录

最近我们的服务器需要嵌入HTTP服务,需要支持httpclient和httpserver,httpclient要同时支持https。我们现在服务器进程之间的网络通信使用的是自有实现,它使用io多路复用技术。因为http只是在tcp之上进行明文传输而已,所以实现也包括了一个简陋的httpclient和httpserver,还基于openssl实现玩具版的https,但基本是不能在生产中使用的。本来我想着用开源库,但看了下好像与epoll结合也挺麻烦,就先自己手撸轮子试试。虽然过程痛苦,但加深了对相关知识的

2022-01-24 20:49:00 1547

原创 printf迷思

一直大概清楚c语言里可变参数的原理(参考C标准库参考指南(上)),所以我在使用printf的时候,都会让格式说明和参数类型严格对应,比如:printf("%llu %d", 8llu, 5);这当然没问题,但有时候发现没对应的时候,不理解printf的实际输出:unsigned long long m = 17179869187; //0x400000003printf("%d %d", m, 9); //3 9 我以为应该是3 4printf("%llu %d", 8, 5, 6); //

2022-01-23 22:44:35 714

原创 理解https的验证过程

我们知道http是明文传输的,所以:1数据可能被窃听和篡改 2察觉不到客户端和服务器之间是否有中间人。为了防止1,可以对数据进行加密:(可以看到https在内容传输的加密上使用的是对称加密)为了防止2,要保证服务器的公钥确实是它的,可以请权威机构对公钥进行数字签名。具体一点就是,签名方有一对密钥,暂称为CA公钥、CA密钥,先计算『服务器公钥和一些比如域名之类的其他信息』的摘要,然后用CA密钥对摘要进行加密,这些信息和加密后的摘要组成数字证书,然后颁发给服务器。当然证书还包括过期时间,颁发机构的指纹

2022-01-01 16:27:02 359

原创 躺平本金估算

我来算一算躺平需要多少钱。基本思路公积金账户里的钱给父母养老,他们勤俭节约惯了,花不了多少钱。他们手里有钱的话就用来预防一些意外吧。我能力有限,也自私,只能出这么多了。证券账户放100万,决定躺平之时用于买房,挣钱了就买好点的房子,赔了就回村里住,花不了什么钱。躺平时装修、买车、以及其他一次性支出20万。再扣除用来交养老保险和医疗保险的钱,定期利息收入与社会平均工资持平就OK了。保险需要多少钱也不清楚别的地方五险一金缴纳比例是多少,就以北京为例养老保险个人8%,单位16%医疗保险个人2%,

2021-11-19 22:58:07 347

原创 c++服务编译耗时优化实践

背景最近服务器编译速度越来越慢,影响开发效率,着手改进。当前环境是:CentOS Linux release 7.2.1511,g++ 4.8.5。方法研究ccacheccache是一个编译缓存工具,其原理是将cpp的编译结果保存在文件缓存中,以后编译时若对应文件无变动可直接从缓存中获取编译结果。由于我们直接用makefile管理项目,会保存.o文件,头文件变化时make会重新生成.o文件,ccache的命中率很低,基本没什么用。distccdistcc是一个分布式编译工具。distcc可以在

2021-11-05 17:53:41 770

原创 c++单元测试框架Catch2的简单使用

Catch2是一个简单的c++单元测试框架,v2版本基于c++11开发,v3版本需要c++14及以上,最初版本Catch1.x基于c++98。项目地址是 Catch2 或 镜像。Catch2简单易用,v2版本只需要下载catch.hpp,先选择v2.x分支,路径是single_include/catch2/catch.hpp,主分支当前是v3版本,将extras目录下的catch_amalgamated.hpp和catch_amalgamated.cpp下载,包含到你的工程就可以了。Catch2不依赖

2021-09-20 16:55:33 4028

原创 c++的复制省略(copy elision)

学习 A simple C++11 Thread Pool 时,发现函数返回了std::future,而std::future的拷贝构造和拷贝赋值都是delete的,感觉有点怪,查了一下,看到 编译器优化之Copy elision、URVO、NRVO 后恍然大悟。这里做一下总结整理。复制省略或者译作省略不必要的复制(copy elision),是C++语言标准中定义的编译优化技术。当一个class类型的临时对象用于初始化同类型的对象时,复制初始化通常优化为直接初始化。GCC的编译选项-fno-elid

2021-08-28 17:36:03 1701 1

原创 赌徒破产问题

罗伯特席勒的《金融市场》第19课结尾提到一个“gambler’s ruin problem”:初始有s块钱,每次交易可能赚钱或赔钱,赚钱的概率是p,赔钱的概率是1-p,每次赚或赔的金额是1块钱,那他破产的概率是多少。知乎上有个类似问题的解答,依照他的思路,我尝试计算赌徒破产的概率:问题先等价转换为,坐标轴上AB两点,A左B右相距s,从A出发,赢往左走1步,输往右走1步,走到B点破产。从任意一点开始,首次到达他+1的点的概率都是相等的,记为f1f_{1}f1​。从任意一点开始,首次到达他+n的点的概

2021-06-27 11:00:34 1919

原创 不要使用TCP的KeepAlive功能

TCP的KeepAlive机制用来检测连接是否存活,它并不是TCP协议规范的一部分,但在几乎所有的TCP/IP协议栈中,都实现了KeepAlive功能。KeepAlive有三个参数:keepalive_time:探测的超时keepalive_probes:探测次数keepalive_intvl:探测间隔对一个已经建立的tcp连接,如果在keepalive_time时间内双方没有任何的数据包传输,则开启keepalive功能的一端将发送 keepalive数据包,若没有收到应答,则每隔keepal

2021-06-03 11:55:01 1034

原创 mysql cppconn读写blob类型数据

这里是通过c++在MySQL中读写blob类型数据的一个例子,这里blob用std::string展示,实际可能是其他类型。//DBPool是一个单例的MySQL连接池#define SmartConn(conn) std::unique_ptr<sql::Connection, std::function<void(sql::Connection*)>> conn(DBPool::GetInstance().GetConnection(), std::bind(&DBP

2021-05-28 19:01:23 578

原创 shell脚本调试方法

-x”选项使shell在执行脚本的过程中把它实际执行的每一个命令显示出来,并且在行首显示一个"+"号, "+"号后面显示的是经过了变量替换之后的命令行的内容,有助于分析实际执行的是什么命令。其中signal是要捕获的信号,command是捕获到指定的信号之后,所要执行的命令,可以是一条或多条合法的shell语句,也可以是一个函数名。在上面的结果中,前面有“+”号的行是shell脚本实际执行的命令,前面有“++”号的行是执行trap机制中指定的命令,其它的行则是输出信息。PS1是主提示符变量,默认值。

2021-04-10 10:35:44 1458

libghttp_1.0.9.orig.tar.gz

The gHTTP library is designed to be simple and easy to use while still allowing you to get your feet wet at the protocol layer if you have to.

2017-10-11

hadoop-common-2.2.0-bin-master.zip

(包含windows端开发Hadoop2.2需要的winutils.exe)

2015-05-12

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除