- 博客(127)
- 收藏
- 关注
原创 封装 brpc::Channel
本文介绍了基于brpc框架的服务管理设计。主要采用Channel作为客户端与服务端的交互通道,通过service_channel封装服务名称与Channel的映射关系。系统设计包含:1)使用数组管理主机节点地址,哈希表建立地址与Channel的映射;2)采用互斥锁保护共享容器;3)实现RR轮转策略均衡分配Channel;4)提供add_host/del_host动态管理节点;5)ServiceManager通过回调函数处理服务上下线事件,并使用互斥锁保护服务集合和服务-通道映射表。该设计实现了服务节点的动态
2025-07-12 18:18:29
150
原创 brpc 的简单使用
本文介绍了使用brpc框架开发RPC服务的基本流程。服务端开发需继承EchoService基类并重写Echo方法处理请求,通过Server类启动服务;客户端通过Channel与服务器交互,使用Stub类发起请求。文章详细说明了服务端处理请求时的参数使用、done回调机制,以及服务启动的四步流程,同时介绍了客户端创建Channel、发送请求的基本步骤,为brpc框架的入门开发提供了实用指导。
2025-07-12 09:57:40
374
原创 brpc 介绍与安装
本文介绍了C++编写的工业级RPC框架brpc,它广泛应用于高性能系统。brpc通过接口调用实现客户端与服务端通信,简化网络编程。安装步骤包括:先安装git、g++等依赖库,再通过git克隆brpc源码,执行cmake构建和make安装。若出错可能因缺失依赖库。全文简要说明了brpc的作用原理和安装方法。
2025-07-12 08:50:15
123
原创 etcd-cpp-apiv3 二次封装
本文介绍了基于etcd的客户端接口封装,主要包括以下内容: 核心接口类: Value类:存储键值对数据 Event类:记录键值对变化事件 Response类:服务器响应 KeepAlive类:租约保活机制 Client类:客户端操作接口 Watcher类:键值对监控 二次封装: Register类:封装Client和KeepAlive,实现服务注册和自动续约 Discover类:封装Client和Watcher,实现服务发现和变更通知 功能特点: 通过租约机制实现服务自动过期 支持服务注册、发现和监控 提供
2025-07-07 15:36:15
302
原创 Ubuntu 安装 etcd 与 etcd-cpp-apiv3
摘要:本文介绍了etcd的安装配置和使用方法。首先通过apt安装etcd-server和etcd-client,然后在/etc/default/etcd中配置节点名称、数据目录、监听URL等参数。启动etcd服务后,使用etcdctl存储键值对,若报错需设置ETCDCTL_API环境变量。最后详细说明了etcd-cpp-apiv3的安装步骤,包括依赖库安装、源码编译和安装。全文提供了从部署到客户端开发的完整流程说明。
2025-07-05 19:17:59
200
原创 spdlog 项目介绍与二次封装
摘要:本文介绍了对C++开源日志库spdlog的二次封装方案。spdlog提供了5个日志等级(trace至critical)和两种日志输出方式(同步/异步)。通过工厂模式创建日志对象,封装后提供了init_logger()初始化接口,可切换调试模式(同步输出trace级以上日志)和发布模式(异步输出指定等级日志)。封装还定义了LOG_DEBUG等宏,自动附加文件名和行号信息,并设置了默认日志格式(时间、日志名、等级、内容)。使用时需链接spdlog和fmt库。该封装简化了spdlog的使用,同时保留了其核心
2025-07-05 12:38:57
812
原创 gtest 库的安装和使用
GoogleTest是谷歌开源的C++单元测试框架,用于验证程序的正确性。安装可通过sudo apt-get install libgtest-dev完成。使用GoogleTest时,通过TEST宏定义测试用例,第一个参数为测试套件名称,第二个参数为测试样例名称。测试框架通过testing::InitGoogleTest初始化,并通过RUN_ALL_TESTS执行所有测试。例如,测试一个计算器类的加法、减法、乘法和除法功能,可以分别编写四个TEST宏,使用ASSERT_EQ断言验证结果。最后,在main函数
2025-05-19 19:24:15
409
1
原创 gflags 安装及使用
gflags是Google开发的一个C++库,用于处理命令行参数。通过包含头文件#include <gflags/gflags.h>,开发者可以使用宏定义命令行参数,如DEFINE_bool、DEFINE_int32等,分别用于定义布尔、整数等类型的参数。定义后,使用google::ParseCommandLineFlags函数解析命令行参数。在代码中使用这些参数时,需加上FLAGS_前缀。gflags还支持通过命令行或配置文件设置参数,如./test --reuse_addr=false或./
2025-05-16 19:20:09
729
1
原创 C++的 I/O 流
我们重点要掌握的是:输入输出流定义的全局对象 cout cin 等, 还有文件输入输出流,熟悉文件输入输出流相关接口。
2025-02-05 16:55:34
1037
1
原创 C++11(中)
类新增成员函数, default, delete, 可变模板参数, STL容器的 emplace_back 系列, lambda表达式, function 包装器, std::bind
2025-01-31 19:31:22
876
原创 C++11(上)
列表初始化 {}。 initializer_list 。auto 。nullptr 。左值与右值 。右值为什么可以提高效率 。模板中的万能引用 。属性退化。 完美转发 std::forward<T>()。
2025-01-23 18:11:10
1289
原创 详解常见的寄存器和中断的概念以及CPU的状态
数据寄存器(DR)用来暂时存放CPU执行指令是用的操作数,运算结果, 中间结果地址寄存器(AR)用来存放中某个数据或指令的地址条件码寄存器(CCR)其标志位由CPU硬件设置,例如,一次算数运算可能导致CCR被设置为正, 负, 零, 溢出程序计数器(PC)存放下一周期被执行指令的指令寄存器(IR)存放待执行的指令程序状态字寄存器(PSW)PSW的各个位代表系统中当前各种不同的状态与信息,例如CPU的优先级,用户态, 核心态等中断现场保护寄存器。
2024-12-19 18:54:20
658
1
原创 操作系统的基本认识
这个词可能或多或少听说过,比如。这些其实都是工程师们经过实践后的产物。而这六个字就是操作系统的抽象化,更准确的说,是很理论化的东西。举一个不是很恰当的例子,和,马哲就是一种比较抽象的理论,而中国特色社会主义是马哲实践后的产物。所以这里要给大家避个坑——如果要学操作系统相关的知识,千万不要盯着操作系统原理去学,一定要从一款具体的操作系统切入(比如Linux)。操作系统原理好比计算机里的哲学,真的很抽象。计算机的硬件(键盘,CPU,显示器,磁盘,内存…)只是冷冰冰的硬件,而操作系统就是硬件的。
2024-12-14 20:07:00
795
2
原创 宽度优先搜索(BFS)思想总结以及做题技巧
上文阐述BFS的两个应用场景,这里我们把BFS算法的模板总结一下,下面是伪代码的形式总结模板//模板一//创建vis数组来标记数组中的元素是否被遍历过,0否1是,也可以用bool表示,m和n表示数组的长和宽//创建队列//进行宽搜//获取队头元素q.pop();//删除队列中的队头元素(...) //如果是树的话,这里获取孩子节点,如果是二维数组的话,就遍历一下周围if(没有越界 && 没有被遍历过 && 符合某种性质) {q.push(...) //入队列//模板二。
2024-12-02 08:16:37
724
2
原创 归并排序思想以及做题技巧总结
这一条件,可以用归并排序的过程来求解,但我们还要知道某个数的原始下标才可以,我们可以用一个index数组(数组初始化为 0, 1, 2, 3 ......)和nums数组绑定——nums数组中的数据怎么挪动,index数组中的数据就怎么挪动,这样我们可以通过index数组找到某个数的原始下标。我们把数组分成左右两个区间,先去左区间找出所有逆序对,再去右区间找出所有逆序对,再一左一右区间找剩余的逆序对。对于归并排序而言,我们只需探讨一左一右区间即可,因为下一层的一左一右区间是上一层的左区间或右区间。
2024-11-27 10:48:50
792
2
原创 快速选择算法解决 top K 问题
top K 问题一般是用堆解决的,时间复杂度为,而快速选择算法是基于快排的思想,时间复杂度逼近。下面,我们用快速选择算法解决一道 top K 的力扣题。只要在数组划分三段的思想上分类讨论,即可实现快速选择算法。
2024-11-24 16:11:29
489
1
原创 字符串相关题解
这道题更像一道语法题,考察对容器的掌握情况。如果按题目要求去模拟,不仅要分析每个字符串,还要判断其他字符串是否是自己的异位词,时间复杂度会很高,代码实现也会很麻烦。如果两个字符串是异位词,那么这两个字符串排好顺序后是一样的,那么我们可以用一张哈希表映射,k值为排序后的字符串,v值为异位词数组。那么遍历完源字符串数组后,哈希表中所有的v值就是结果N个字符,排序会消耗O(N⋅log(N)) 时间。
2024-11-16 13:53:16
459
原创 一文搞懂链表相关算法
为了防止cur找不到下一个节点,要提前用next保存起来,cur遍历到的节点都会放到newNode的后面,当cur遍历完整个链表后,newNode后面就是逆序后的链表。用快慢双指针算法。慢指针 slow 每次移动一个节点,快指针 fast 每次移动两个节点,slow 和 fast 都初始化(指向)为链表的头节点, 算法如下
2024-11-13 17:08:46
1102
2
原创 【力扣刷题】【滑动窗口算法】水果成篮
2.判断哈希表中的果树种类,如果种类个数为2,更新结果(区间的长度区较大值),如果种类的个数大于2,一直出窗口更新哈希表。用哈希表记录一个区间内果树的种类和对应的数量。当果树的数量在哈希表中为0的时候,就把该果树从哈希表中移除。1.区间相当于窗口,先入窗口,更新哈希表。那区间要怎么维护呢?
2024-11-06 10:52:05
219
2
原创 一文彻底搞懂二分算法的细节
非朴素二分是在朴素二分的思想上进行泛化,判断一道题是否需要二分算法不在是“数组是否查找区间左端点循环条件:left < right下标更新:if (...) left = mid + 1;中点值mid:left + (right - left) / 2查找区间左端点循环条件:left < right下标更新:if (...) left = mid;中点值mid:left + (right - left + 1) / 2模板的思想总结当下标更新为if (...) left = mid + 1;
2024-11-06 10:50:03
1102
2
原创 【力扣刷题】【滑动窗口算法】最大连续1的个数 III
这题读起来有些抽象,它让找数组中连续 1 的最大个数,但连续的 1 中又可以有最多 k 个 0。乍一看没啥思路,其实这这题目可以换一种问法——在子数组中包含 k 个 0 的子数组的最大长度是多少?检查 0 的个数是否超标: 如果超标,依次让左侧元素滑出窗⼝,顺便更新哈希表的值,直到 0 的个数恢复正常;那么我们只需在数组中维护一段区间,当区间的0的个数等于 k 时,我们就更新结果。程序到这⾥,说明窗⼝内元素是符合要求的,更新结果;right++ ,处理下⼀个元素;让当前元素进⼊窗⼝,顺便统计到哈希表中;
2024-11-05 20:46:52
263
1
原创 【力扣刷题】【滑动窗口算法】无重复字符的最长字串
空间复杂度上我们可以用一个哈希表,把空间复杂度降为O(1)。哈希表中存储某个区间字符和字符出现的次数的映射,但我们不必真的定义一个std::unordered_map。暴力解法是用两层循环列举出所有可能,并用O(N)的空间复杂度存储临时的字符来判断某个区间是否重复了。如果这个字符出现的频次超过 1 ,说明窗⼝内有重复元素,那么就从左侧开始划出窗⼝,如果没有超过 1 ,说明当前窗⼝没有重复元素,可以直接更新结果。直到 ch 这个元素的频次变为 1 ,然后再更新结果。
2024-11-02 15:33:07
276
1
原创 【力扣刷题】【滑动窗口算法】长度最小的子数组
上图中,灰色的区间已经是符合条件的区间了,此时黑色指针向右移动一格,如果是暴力算法,红色指针应该重置到黑色指针的位置,然后向右遍历。我们来讨论一下,红色指针有必要重置吗?题目里说数组里的都是正整数,当区间里已经符合条件了,我们还需要把最右边的指针重置到左边吗。2.灰色区间不符合条件,红色指针被重置后遍历,由于整个区间都是正整数,灰色区间的大小只会增加。1.灰色区间依旧符合条件,红色指针被重置然后遍历,依旧是当前的灰色区间。用两个指针,两层循环,列举出所有的结果,把每次符合的最优结果更新到临时变量里。
2024-11-02 14:51:02
415
1
原创 muduo库TcpConnection类源码解析——链接管理
enum StateE { kDisconnected, //断开连接状态kConnecting, //尝试建立连接的状态kConnected, //成功建立连接的状态kDisconnecting //正在断开连接的状态//把一个链接挂接到EventLoop上进行事件监控//链接的名字//链接的状态 // FIXME: use atomic variable//为true表示链接正在进行读事件监控//IP地址的简单封装//新建链接的回调//消息到来的回调//低水位线回调。
2024-10-27 13:45:06
1233
9
原创 muduo库Buffer类源码解析
我之前写过一篇文章,其思想就是来源于muduo库Buffer类的源码。但代码的细节个人不是很满意,这篇文章带你探秘muduo源码是怎么实现用户级缓冲区。为什么要有用户级缓冲区?在网络通信中TCP的缓冲区是内核缓冲区,要拿到数据,在用户和内核之间始终有一次拷贝,这样似乎就有理由需要一层用户缓冲区来保存数据。但这样的理由似乎是不充分的,因为缓冲区不是处理数据的地方,如果要进行数据处理还需要一次拷贝,似乎,有些浪费性能了?
2024-10-27 09:44:31
963
2
原创 muduo库EventLoop类源码解析
EventLoop也称为事件循环,从调用epoll_wait系统调用捞取到就绪事件到再次阻塞到epoll_wait上(阻塞到内核中的就绪队列上了)称为一次事件循环。muduo库的EventLoop在捞取完就绪事件后会立即执行就绪事件的回调。EventLoop还有一个线程安全的任务队列。在执行完就绪事件的回调后不会立即阻塞到epoll_wait上,他会在执行完任务队列中的任务后在阻塞到就绪队列上。为什么要搞一个线程安全的任务队列呢?muduo库的设计思想是。
2024-10-26 15:42:09
1288
9
原创 高并发服务的核心机制——IO多路转接--->epoll
用于创建epoll模型,返回值是一个文件描述符,也可以理解为epoll模型的一个句柄(Linux里一切接文件)。epoll将会把发生的事件赋值到events数组中 (events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮助我们在用户态中分配内存).当就有文件描述符上的事件就绪了,epoll模型中还有一个双向链表结构,这个数据结构用来存放就绪事件,epoll_wait就是在这上面捞取就绪事件。: 表示对应的文件描述符有紧急的数据可读 (这里应该表示有带外数据到来);
2024-10-26 09:41:56
758
原创 【小洛的VLOG】Web 服务器高并发压力测试(Reactor模型测试)
Webbench,这个工具大家可以搜一下相关的文章,很轻量化,上手成本很低。下载下来只需make编译一下即可,如果你编译不过的话就是有个头文件会报错,根据报错提示,把Webbench源码里报错的头文件去掉就可以啦~Webbench的原理也很简单,就是创建多进程然后同时向服务端发起请求。我用了两台云服务器来模仿服务端和客户端,配置都是2核2G的(恼火),没钱买配置高的服务器(哭)。软件方面是我模仿muduo库写的一个Reactor。
2024-10-20 19:55:46
672
3
原创 【C++】设计用户级缓冲区
底层的容器用std::vector类型。两个下标用uint64_t类型【C++】详解STL容器之一的 vector_c++ vector扩容缩容-CSDN博客//缓冲区//读下标//写下标拷贝数据用std::copy,第一个参数:从哪里拷贝的起始地址,第二个参数:从哪里拷贝的末尾地址,第三参数:从拷贝到哪里的起始地址。查找字符用C语言的strchr,第一个参数:一段空间的起始地址,第二个参数:要查找字符的ASCII,找到了返回字符的地址,失败返回nullptrReadSize。
2024-09-28 14:35:41
2122
89
原创 【C++】C++17中可以存储任意类型数据的对象——any类的使用与设计思想
一提到存储任意类型,第一时间想到的可能就是STL容器,这种容器都是模板。但是,模板类在实例化对象是都要指定类型,例如。那么模板实例化的对象存储的数据类型就是固定的。C++17提供了std::any类,头文件是。any类实例化的对象可以存储任意类型的数据,本文会为大家介绍如何使用any类以及any类是如何实现的。
2024-09-26 11:05:33
1412
65
原创 【C++】检测TCP链接超时——时间轮组件设计
参考钟表的策略,我们可用一个数组代表一个钟表,数组的下标代表时间,指向数组的指针按特定的时间向后移动,指针执行哪个位置,就代表哪个位置的时间到了。智能指针shared_ptr用于任务类的超时时间刷新,在上文提到的高并发服务的场景中,如果触发了链接中的事件,就需要重新刷新时间,但时间轮的指针是一直向后移动的,任务类的下标迟早会被指到,然后该类就会被析构。在我们上述的阐述中,任务是有超时时间的,当时间轮的指针指向这个任务时,说明时间到了,我们该执行这个任务呢——答案是把任务的执行放到析构函数里。
2024-09-24 18:29:58
3660
56
原创 【网络】详解HTTP协议的CGI机制和CGI进程
CGI机制是HTTP协议提供的偏底层的一套机制,也是非常重要的机制——它让大量的业务进程和HTPP协议解耦。而CGI进程是业务层的,用来处理各种数据,比如把用户提交上来的数据插入数据库,再比如做某种运算。CGI机制和CGI进程在概念上是完全不一样的,他们的关系就行老婆和老婆饼一样。客户端通过HTTP协议向服务器提交数据的方式主要有两种:1.GET方法请求,GET方法没有请求正文,一般用来拉取服务器的数据,但也可以通过URL的参数提交数据(URL中?分隔符后面的就是要提交的数据)
2024-09-18 11:34:52
849
21
原创 【Linux系统编程】用互斥量和信号量加锁STL容器,避免并发问题
STL容器并没有保证线程安全,而大多数应用场景下,为了追求效率,多线程是必不可少的。线程先去申请信号量资源,申请到了信号量资源的线程再去竞争互斥量,谁能锁住互斥量,谁就去容器里操作。有了信号量和互斥量的存在,在任意时刻,有且只能有0或1个生产者,0或1个消费者线程在容器里操作。给容器设计两个接口,push()用来向容器填充数据,pop用来向容器取数据。调用push接口的称为生产者,调用pop接口的称为消费者。本文给出的方案是用信号量和互斥量封装vector容器——用两个信号量和两个互斥量封装出环形队列。
2024-09-17 10:14:37
639
7
原创 【Linux系统编程】子进程被程序替换后,如何保持父子进程的通信
子进程exec系列函数后会被目标程序替换,其进程的代码和数据会被替换,但内核数据结构不会被替换(包括文件描述符,环境变量)。建立好信道后,如果直接进行程序替换,被替换后,代码和数据会被目标程序的代码和数据替换掉,那么目标程序也就不知道信道的文件描述符,也就无法和父进程通信。然后再执行exec系列函数,子进程想从信道里读数据,改向标准输入里读,子进程想向信道里写数据,改向标准输出里写。但是每个进程有3个文件描述符是一定确定的0 , 1, 2——分别是标准输入,标准输出,标准错误。方案一:文件描述符的重定向。
2024-09-16 16:06:40
1204
17
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人