
C/C++
文章平均质量分 54
开始学编程
APX7409
专注后端、C/C++开发的菜鸟,相信日拱一卒、功不唐捐。欢迎各位对博文批评指正,互相学习
展开
-
24校招总结
之前实习也是游戏后端开发,不过用的是erlang,消息协议用的都是PB、然后实习一个多月的话,个人就是感觉刚进去用的比较多的是 Linux指令、git、还有C++ STL的熟练使用(有时候需要用到它来做数据转换),像网络框架的话目前本人水平有限,都是组里的前辈在维护,我主要工作是使用框架,了解大佬们写的战斗逻辑,能够在这个基础上做一些修改以及BUG的修复以及游戏角色的技能制作等。整个校招期间从去年9月到今年年初投了快接近200家公司,现在想想不应该啥都投,光花在填简历的时间就很多。硕士:B区双非计算机硕。原创 2024-05-27 22:00:47 · 852 阅读 · 0 评论 -
cpp杂项知识点(一)
原来的指针就不再拥有这个对象了。在拷贝/赋值过程中,会直接剥夺指针对原对象对内存的控制权,转交给新对象,然后再将原对象指针置为。可以看出 i1 为 5,我们实际书写的时候应该是 00 00 00 05, 但是内存打印的结果是颠倒的,数据低位存到地址低位,即。要求:求得"123" 的全排列,即 123,132, 213, 231, 312 ,321。若不对相同的数处理,则会导致相同的数交换结果为0,因为相同异或结果为0。就完成了运算,查看反汇编代码的时候可以看出直接得到了结果。,默认获取升序的下一个排列。原创 2024-02-17 11:06:38 · 470 阅读 · 0 评论 -
分布式网络通信框架(十五)——Mprpc项目总结
会一直阻塞下去),也就是指定的timeout时间内没有收到rpc 请求的响应,判断当前rpc 请求失败,此处为了实现高可用性,可以再尝试请求比如3 次,3 次都失败的话,可以从zookeeper 上查询还有没有其它主机提供同样的rpc 服务,然后重新向新主机发起请求,直到请求成功,如果所有提供该rpc 服务的主机都没有响应或已经没有其它主机提供该rpc 服务了,那么尝试3 次后,可以判定请求失败(确实有其它因素导致所有的服务器都挂掉了,这一般是严重的线上bug)。,封装了很好用的接口,之前只用过json。原创 2023-05-29 10:43:38 · 6260 阅读 · 3 评论 -
分布式网络通信框架(十四)——使用mprpc编写客户端(服务调用方)程序示例
这个静态库和对应头文件,进行编译生成可执行文件。原创 2023-05-29 10:26:58 · 421 阅读 · 0 评论 -
分布式网络通信框架(十三)——zookeeper C++客户端编程
zookeeperC++客户端编程很类似于MySQL客户端编程,就是以C++代码实现zk客户端的常见功能,比如getdeletecreate等.原创 2023-05-29 10:19:05 · 2415 阅读 · 0 评论 -
分布式网络通信框架(十一)——logger日志系统设计实现
模板类的声明和成员函数实现最好都是实现在同一个头文件,分文件编写可能造成链接错误,日志模块是生产者消费者模型。工作方式,多个线程往队列写日志,一个专门的写线程从队列中读取日志信息写入磁盘中的日志文件。:线程安全,线程间通信,队列,生产者消费者模型。本项目所实现的日志模块采用。原创 2023-05-29 09:47:24 · 525 阅读 · 0 评论 -
分布式网络通信框架(十)——Mprpc框架使用示例
然后在客户端(服务调用方caller)业务代码中使用Stub对象来调用希望调用的方法,并且接收响应。主要的工作就是实现一个新类继承于 UserServiceRpc,并且重写其对应的虚函数。生成的.h文件中找函数的声明,如Login)然后自己实现一个提供服务的.cc文件(如。)和服务方法成员,以及一些相关的消息(),其中提供获取好友列表的rpc方法(类型,然后再添加希望提供的服务。)和 其中的方法 rpc (如。) ,并且重写对应的方法(从。文件,让其生成对应的服务类(的业务代码中实现一个继承。原创 2023-05-28 21:26:29 · 1216 阅读 · 0 评论 -
分布式网络通信框架(九)——RpcChannel调用过程
客户端使用RpcChannel对象来构造对象,并利用该对象中来进行rpc调用请求,RpcChannel。原创 2023-05-28 21:02:30 · 628 阅读 · 0 评论 -
分布式网络通信框架(八)——RpcProvider分发rpc服务
分发rpc服务,我们实现的框架代码就是主要完成如下红圈部分的任务:客户端(请求调用方)发送请求时需要发args_size, 其中args_size防止粘包问题,于是采用如下的消息格式设计(消息成员长度,占4B) +header_str(消息成员)// 定义RPC请求头消息格式// 请求的服务名// 请求的方法名// 请求的方法的参数大小。原创 2023-05-28 20:51:45 · 714 阅读 · 0 评论 -
分布式网络通信框架(七)——RpcProvider发布服务方法
利用muduo库的来实现数据的收发,利用protobuf来实现数据的序列化(发送前)和反序列化(接收后)发布服务主要在实现,重点在于生成一张表,记录服务对象和其发布的所有服务方法// 保存服务对象的地址 std :: unordered_map < std :: string , const google :: protobuf :: MethodDescriptor * > m_methodMap;// 保存服务方法映射<方法名, 方法描述符指针> };原创 2023-05-28 20:10:43 · 554 阅读 · 0 评论 -
分布式网络通信框架(六)——开发RpcProvider的网络服务
因为RPC服务器必然是要接受大量客户端的调用请求,所以需要一个。原创 2023-05-28 20:03:03 · 629 阅读 · 0 评论 -
分布式网络通信框架(五)——Mprpc框架基础类设计
根据上面的需求,我们可以设计两个类。原创 2023-05-28 19:55:08 · 715 阅读 · 0 评论 -
分布式网络通信框架(四)——本地服务发布成RPC服务
通过这个例子,目的在于了解RPC框架在服务提供方servercallee)的使用,从而更好理解实现代码。原创 2023-05-28 19:50:30 · 729 阅读 · 0 评论 -
分布式网络通信框架(三)——protobuf使用案例
下面的例子使用service关键字定义描述rpc方法的类型,并且注意开头要设置option// 声明了protobuf版本// 声明了代码所在的包(生成C++代码后就是namespace 名字)// 定义下面的选项,表示生成service服务类和rpc方法描述,默认不生成// 定义登录消息类型// =1 代表name是这个message第一个字段,不是指name的值// 定义登录响应消息enum SexMAN = 0;WOMAN = 1;原创 2023-05-28 19:36:17 · 1727 阅读 · 0 评论 -
分布式网络通信框架(二)——RPC通信原理和技术选型
也就是数据的序列化和反序列化,用。方法调用的序列化和反序列化。服务配置中心(服务发现):设计rpc方法参数的。不需要存储额外信息;:顶层的cmake文件。:网络部分,包括寻找。原创 2023-05-28 17:06:19 · 755 阅读 · 0 评论 -
分布式网络通信框架(一)——集群和分布式
每一个模块独立部署运行在一个服务器主机上,所有服务器协同工作共同提供服务,每一台服务器称作分布式的一个。机器1上的一个模块进程1怎么调用机器1上的模块进程2里面的一个业务方法呢?1可以再集群部署出分布式节点1-1,分布式节点1-2,…大系统的软件模块怎么划分?机器1上的模块怎么调用机器2上的模块的一个业务方法?比如后台管理不需要高并发,所以不需要每台机器都部署。密集型,造成各模块对硬件资源的需求是不一样的。,根据节点的并发要求,对一个节点可以再做。虚拟化环境中),各模块之间该怎么访问呢?原创 2023-05-28 17:01:05 · 2289 阅读 · 2 评论 -
cpp11实现线程池(九)——使用packaged_task和future重写线程池
r1和r2放入队列,被两个线程取走,然后r3和r4再将任务放入队列(任务队列满),此时由于r1和r2任务中有sleep仍然被两个线程执行中,此时任务队列已满,主线程无法将r5放入任务队列。设置为 2,提交6个任务(其中3个睡眠2s),线程池只有两个线程。:让提交任务更加方便,我们希望能达到如下形式提交任务。,重点在于任务的封装。原创 2023-05-21 15:51:36 · 648 阅读 · 0 评论 -
cpp11实现线程池(八)——Linux平台编译线程池动态库
将threadpool.cpp 和 threadpool.h编译成。执行可执行程序但是失败,因为运行时系统寻找动态库位置有所不同。如果是老版本的g++,则可能会出现死锁的现象,是由于g++下。再次执行程序,程序正常运行,乱码是编码问题。值标识是否已经退出,若退出就不要做加锁和。添加一行 /usr/local/lib。命令将用户切换为root用户,紧接着回到测试文件路径,可以使用gdb调试线程。析构不做任何事,导致。原创 2023-05-21 14:53:09 · 264 阅读 · 0 评论 -
cpp11实现线程池(七)——线程池cached模式设计实现
用vector::size() 获取当前容器元素数量不是的,所以采用atomic_int 来实现当前容器元素数量的改变能够保证线程安全。原创 2023-05-21 14:34:34 · 767 阅读 · 0 评论 -
cpp11实现线程池(六)——线程池任务返回值类型Result实现
提交任务函数submitTask中返回的Result类型应该是用Result类包装当前的task,因为出函数之后taskResult和Task都要互相持有对方的指针,Task要将任务执行结果通过调用传给其对应Result对象。原创 2023-05-21 14:15:49 · 1070 阅读 · 0 评论 -
cpp11实现线程池(五)——使用mutex和condition_variable实现Semaphore
以及一个记录数值的变量来实现,注意信号量。原创 2023-05-21 11:49:21 · 179 阅读 · 0 评论 -
cpp11实现线程池(四)——Any类实现原理
需要让一个类型指向其他任意类型,用基类类型可以指向派生类类型。能够获取任务执行结果,同时任务未执行完成时会在。函数的返回值,可以表示任意类型。:如何设置执行任务获得的。原创 2023-05-21 11:43:55 · 182 阅读 · 0 评论 -
cpp11实现线程池(三)——生产者与消费者线程函数实现
线程池中,生产者线程(主线程 Master)的主要工作是给任务队列提交任务函数实现;而消费者线程(Slave)主要工作是从任务队列取任务并执行任务函数。原创 2023-05-21 11:27:19 · 253 阅读 · 0 评论 -
cpp11实现线程池(二)——ThreadPool相关类的设计
enum class能够确保枚举项相同时可以区分开来,如。原创 2023-05-21 11:11:51 · 218 阅读 · 0 评论 -
cpp11实现线程池(一)——项目介绍
线程池是库的形式提供给用户,是必须放到代码中,不能单独运行,亦称为基础组件第一版线程池任务对象使用继承技术,提供一个抽象基类Task,里面有一个纯虚函数run(),使用时继承该类,并重写该纯虚函数,在这个重写的纯虚函数中完成要执行的具体任务;第二版线程池使用C++11 的来包装任务执行函数,用来接受任意类型的结果。原创 2023-05-21 11:01:21 · 986 阅读 · 0 评论 -
Nginx内存池移植为C++版本
这个项目是在阅读nginx内存池源码后,将其代码重新用C++面向对象的方式实现,大体与源码相同,旨在加深对nginx内存池的理解。// 内存池实际的可分配内存空间 p -> max =(size < NGX_MAX_ALLOC_FROM_POOL)?pool = p;return p;u_char * m;// 到下一个小块内存池尝试 } while(p);u_char * m;原创 2023-05-17 15:12:59 · 224 阅读 · 0 评论 -
Nginx内存池(六)——内存池源码编译测试
将测试代码文件移动到nginx-1.12.2根目录下,然后执行相应的编译指令。删掉 (-Werror,它要求GCC将所有的警告当成错误进行处理),所以析构时先调用func2()在调用fun1()清理操作对象的添加函数。原创 2023-05-17 14:52:02 · 185 阅读 · 0 评论 -
Nginx内存池(五)——外部资源释放和内存池销毁
假如内存中有存储指向动态开辟内存的指针,调用ngx_pfree只是简单的释放了大块内存的空间,而其中指针指向的内存空间并没有被释放,这会导致内存泄漏。为此nginx内存池提供了一个用户可自己设置的回调)来进行这一类资源的释放,这个清理资源操作对象可能有多个用链表组织,内存图示如下。原创 2023-05-17 14:40:47 · 359 阅读 · 0 评论 -
Nginx内存池(四)——重置函数和小块内存回收策略
http服务器(nginx)返回响应后需等待60s,60s之内客户端又发来请求,重置这个时间,否则60s之内没客户端发来响应,ngnix就主动断开连接,此时nginx可调用。就主动断开TCP链接(http 1.1 keep-alive:60s)服务器,客户端发起一个request请求,到达。中只有释放大块内存而没有释放小块内存的函数;Ngnix则是只提供了内存池重置函数。,等待下一次该客户端请求。原因是应用场景的问题,原创 2023-05-17 14:32:43 · 355 阅读 · 0 评论 -
Nginx内存池(三)——大块内存分配分配释放
到后面再创建大块内存时可以。,可查看分配函数中M1代码处。原创 2023-05-17 14:25:11 · 197 阅读 · 0 评论 -
Nginx内存池(二)——小块内存分配
如果内存池空闲空间大于需要分配的内存大小,则可以直接分配,否则进入到下一个内存池进行分配,若都没有则进入。可以看出除第一个内存池外,后面内存池只需要占额外的。原创 2023-05-16 16:02:56 · 155 阅读 · 0 评论 -
Nginx内存池(一)——类型和重要函数定义
类型定义重要函数创建内存池剖析原创 2023-05-16 15:52:10 · 112 阅读 · 0 评论 -
SGI STL内存池源码移植
SGI STL内存池源码移植要考虑线程安全问题,因为是在容器中使用,这个移植的工作主要就是将SGI STL的二级空间配置器抽取出最小的部分实现我们自己的二级空间配置器从而能够应用在容器中。原创 2023-05-16 15:33:51 · 100 阅读 · 0 评论 -
SGI STL(七)——内存池总结
防止小块内存频繁分配、释放、造成很多的碎片出来,内存没有更多的连续的大内存块,所以应用对于小块内存的操作,一般都会使用内存池来进行管理对于每个字节数的chunk块分配,都是给出一部分进行使用,另一部分作为备用(开内存的时候*2),这个备用可给当前字节数使用,也可给其他字节数使用对于备用内存池划分完chunk块后 ,若还有剩余的很小内存块,再次分配时,会把这些小的内存块再次分配出去,备用内存池能够得到完美利用当指定字节数分配失败时,有一个异常处理。原创 2023-05-16 15:04:37 · 225 阅读 · 0 评论 -
SGI STL(六)——reallocate函数解析
函数主要用于内存池的。原创 2023-05-16 14:57:55 · 244 阅读 · 0 评论 -
SGI STL(五)——deallocate函数解析
内存池中小块内存释放采用头部归还的方式,归还块的指针指向空闲块链表头,将空闲块链表头修改为新归还的块的地址类似于重写对象的new和delete实现对象池的组织方式。原创 2023-05-16 14:55:29 · 122 阅读 · 0 评论 -
SGI STL(四)——_S_chunk_alloc函数解析
错误时的处理函数,进入该函数后,可以进行错误的处理,如果用户有设置对应处理函数,就会死循环直到内存分配成功。的逻辑,由于剩余空间大于0,则进行内存碎片的处理:把剩余的空间挂接到合适单位字节的trunk块上,即32B的trunk块上,指针做出了如下的变化。即(320 >= 160),将内存小块分配给用户,指针向下移动,即(这里指针画错了,是8字节的。, 即希望分配8个20B的内存小块构成的。),如下图(这里指针画错了,是8字节的。,故可以复用备用的内存块即进入代码的。,但是可以看到8B的。原创 2023-05-16 14:49:02 · 361 阅读 · 0 评论 -
SGI STL(三)——_S_refill函数解析
该函数功能是给中_Obj*为空的项建立空闲链表,即创建一个由多个相同内存小块构建成的大块chunk,并且使得每个小块指向下一个空闲小块。原创 2023-05-16 14:27:42 · 118 阅读 · 0 评论 -
SGI STL(二)——allocate内存分配函数
的逻辑(chunk块有内存小块可分配),图示如下。内存分配函数关键代码如下。使用二级空间配置器并进入。原创 2023-05-16 14:18:18 · 155 阅读 · 0 评论 -
SGI STL(一)——容器allocator概述
SGI STL有两个allocator(空间配置器)一级allocator内存管理使用;二级allocator使用内存池实现容器底层存储的对象的构造和析构,定义的是全局的函数模板construct和destroy// 调用定位new ++ _M_finish;// 转调用析构函数 } void allocator :: construct(pointer __p , const _Tp & __val) {// 内存池的粒度信息 enum {原创 2023-05-16 14:13:16 · 119 阅读 · 0 评论