- 博客(52)
- 收藏
- 关注
原创 ROS学习过程记录(二)
查看自定义消息printf("我的枪去而复返,你的生命有去无回!\n");printf("我的枪去而复返,你的生命有去无回!\n");printf("我要开始刷屏了!\n");msg . grade = "王者";msg . data = “国服马超,带飞";} return 0;printf("我的枪去而复返,你的生命有去无回!\n");printf("我要开始刷屏了!\n");msg . grade = "王者";msg . data = “国服马超,带飞"
2025-03-17 20:09:09
835
原创 ROS学习过程(一)
如果你的系统中有多个子系统(如传感器、控制器、规划器等),你可以将每个子系统的节点配置到不同的 launch 文件中,并通过 标签将它们组合在一起。如果队列里有多条消息,spinOnce() 只会触发一次回调函数,处理其中最早的一条,剩下的消息要等下次调用 spinOnce() 时才会继续处理。spinOnce() 会依次检查所有的订阅者,并调用每个订阅者的回调函数。ssr_pkg是创建的包名,后面是依赖项,创建好新包后,在CMakeLists.txt会有对包的依赖,package.xml中也有依赖项。
2025-03-13 21:48:52
535
原创 sanitizer和valgrind
发现sanitizer程序要正常退出才能给出分析,ctrl+c退出不行,valgrind ctrl+c退出也可以给出分析。使用上sanitizer加编译选项即可。
2025-03-09 21:16:32
208
原创 enable_shared_from_this
考虑以上代码,从一个被shared_ptr管理的struct中返回一个shared_ptr,明显这是有问题的,两个shared_ptr管理的是同一个this,会free两次,那么本质上就是,当我们有用一个this指针时,如何得到对应的shared_ptr呢。就可以实现,这种模板类可能少见,因为继承的父类的模板参数是子类,这是因为父类需要知道子类的类型去生成对应的函数. 这种称为奇异递归模板模式,可用来实现静态多态,参考。如此便可,可以看到继承一个enable_shared_from_this。
2024-12-11 21:47:49
294
原创 探究有栈协程的实现以及ucontenxt函数族的使用
ucontext.h是GNU C库的一个头文件,主要用于用户态下的上下文切换。可见有栈协程的原理并不算高深,就是保存寄存器,单独弄个栈空间赋值进去,然后调用系统调用,将新的栈地址、程序计数器写入CPU。这里每个协程都有单独的栈空间,这样使用倒是很方便,就是有点浪费,由此引入了共享栈,共享栈其实也不神秘,即所有协程公用一个栈空间,但是切换时,会将当前栈空间的内容全部memcpy的协程的数据结构中,恢复时再从其中拷贝到共享栈中。
2024-12-11 21:00:18
973
原创 RPC设计--TcpConnection和TcpServer
对于写,则是应用层调用写接口,将其写入到TcpBuffer中,当Fd发生可写事件后,调用写方法TcpConnection::write,将TcpBuffer中的数据写到fd中。在可写事件执行完后,需要将其从epoll中删除,等到需要发送数据时才添加写事件,因为fd大部分时候是可写的,就会一直触发可写事件,既然OutBuffer中的数据已经全部写到fd中了,就应该删除该事件。在可读事件执行完后,不需要将fd的可读事件移出,因为当前这个IO线程本身就是为该通信fd服务的,始终监听fd的可读事件。
2024-12-08 23:28:39
542
原创 RPC设计--TcpAcceptor
可提供getListenFd方法,以此构建FdEvent对象,提供accept方法,当listenfd上有客户端连接时调用,返回clientfd、client端地址。其功能较为简单,把套接字通信的一整套流程封装起来。在构造函数中就创建好连接套接字、设置好端口复用,等待accept,即自己封装socket 、 bind等函数调用。传入本地要监听的地址和端口,完成上述流程。
2024-12-08 22:21:54
356
原创 RPC设计--应用层缓冲区,TcpBuffer
提供readFromBuffer接口,从读索引位置开始读数据,读完指定的字节数后,判断是否需要进行读写索引的调整,因为这里不是环形缓冲区,当写入数据,读出来后,buffer前面的空间已经可用了,但是读写索引都指向了靠后的位置,导致可写空间不够。提供writeToBuffer接口,当用数据写入时,将数据从write_index位置向后写,如果缓存空间不够,需要进行扩容,写完数据后,需要增加write_index对应的字节数。参考其中的tcpbuffer.cpp/h。可提供可读字节数、可写字节数等接口。
2024-12-08 22:14:14
430
原创 RPC设计--从reactor设计 (IOthread)
一般的一个网络IO库都是主从reactor模式,即主线程中有一个MainReactor,其负责监听ListenFd,当接受到新的用户连接时,返回的clientfd并不会加入的MainReacotr,而是在子线程(这里称为IO线程)中,创建一个新的event_loop(即从Reactor, subreacotr),将clientfd加入到此SubReactor中,这样的架构称为主从reactor架构。其中io_thread.cpp 和io_thread_group.cpp。
2024-12-08 21:45:08
429
原创 RPC设计--EventLoop和FdEvent
这里的wakeup_fd手段是必要的,因为EventLoop线程大多时候阻塞在epoll_wait中,当需要EventLoop退出或进行处理时(如添加事件),又需要EventLoop线程自身做,所以需要一套通知机制,发一个通知,让epoll_wait返回,去执行对应的任务,而对应的任务本身就通过回调函数传入。接下来需要执行这个回调函数,一般的需要异步执行这个回调函数,所以在EventLoop内部会放一个任务列表,也就是一个回调函数的列表:pending_tasks。
2024-12-02 11:43:54
425
原创 RPC中定时器制作思路
执行完成后,需要重置到期时间,以time_events中第一个到期的时间设置成timer_fd的时间,即下次epoll_wait返回,调用OnTime的时间。timer是具体的定时器类,内部包含多个time_event,由于多个time_event可能有相同的执行时间,可以采用std::multimap 这些time_event, 其中key为执行时间戳,value为time_event.构造函数传入这些参数,即1:到期执行的任务函数 2:重复间隔时间 3:首次执行的时间戳。
2024-12-01 23:45:37
310
原创 vscode安装clangd, clangd报错,代码飘红(pp_file_not_found)解决办法
对于makefile编译的项目,在makefile编译的项目中,使用bear命令,运行bear make, 会在当前目录下生成compile_commands.json, 之后在vscode的 clangd的设置中,设置compile_commands.json路径。将/your/json/path 替换为自己的compile_commands.json绝对路径后, 重启窗口,之后clangd就可正确找到依赖关系。而默认是没有这个文件的,导致出错。
2024-11-29 00:18:33
888
原创 探究C++ std::funcion的实现
std::funcion 可以接受函数指针,lambda表达式,以及重载了operator()的类,这里讨论其实现原理。在修改版中,引入了一个中间层,FuncBase和FuncImp, MyFunction中有一个FuncBase指针,而FuncImp从FuncBase派生而来;
2024-11-25 21:25:42
626
原创 C++设计模式-职责链
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。应用于”一个请求可能有多个接受者,但是最后真正的接受者只有一个“,这时候请求发送者与接受者有可能出现”变化脆弱“的症状,职责链解耦。有些过时。
2024-11-25 09:12:31
290
原创 C++设计模式-状态模式
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。State模式将所有与一个特定状态相关的行为都放入一个State的子对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。转换是原子性的与Strategy模式类似。
2024-11-25 09:12:17
437
原创 C++设计模式-中介者模式
用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各对象不需要显式的相互引用(编译时依赖->运行时依赖),从而使其耦合松散(管理变化),并且可以独立地改变它们之间的交互。将多个对象间发杂的关联关系解耦Facade模式是解耦系统间(单向)的对象关联关系;Mediator模式是解耦系统内各个对象之间(双向)的关联关系。
2024-11-24 16:10:50
545
原创 C++设计模式-适配器模式
将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。在遗留代码复用、类库迁移等方面有用。
2024-11-24 16:07:56
320
原创 C++设计模式-代理模式
为其他对象提供一种代理以控制(隔离,使用接口)对这对象的访问。Proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。
2024-11-24 16:00:35
320
原创 C++设计模式-Facade 门面模式
为子系统中的一组接口提供一个一致(稳定)的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用)。从客户程序角度来看,Façade模式简化了整个组件系统的接口,对于组件内部与外部的客户程序来说,达到了一种”解耦“的效果——内部子系统的任何变化不会影响到Façade接口的变化。Façade设计模式更注重架构的层次去看整个系统,而不是单个类的层次。Façade很多时候是一种架构设计模式。Façade设计模式并非一个集装箱,可以任意地放进任何多个对象。
2024-11-24 15:56:42
345
原创 C++设计模式-单例模式
保证一个类仅有一个实例,并提供一个该实例的全局访问点。代码示例private:public://线程非安全版本//线程安全版本,但锁的代价过高Lock lock;//双检查锁,但由于内存读写reorder不安全Lock lock;// 这里有三步//1: 申请内存 2:在内存上调用构造函数 3:将内存地址赋给m_instance//但可能发生的顺序为132,由此变成了不安全的版本//C++ 11版本之后的跨平台实现 (volatile)
2024-11-24 15:40:57
556
原创 C++设计模式-抽象工厂
提供一个接口,让该接口负责创建一系列”相关或者相互依赖的对象“,无需指定它们具体的类。//数据库访问有关的基类public:public:public://支持SQL Server//支持Oraclepublic://关联性//关联性代码中的Connection、Reader、Command为一系列的工厂,有关联关系,那么将一系列的关联关系的类组合到一起,抽象工厂。//数据库访问有关的基类。
2024-11-24 15:17:00
172
原创 C++设计模式-工厂方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。Factory Method模式解决“单个对象”的需求变化。
2024-11-24 15:12:09
131
原创 C++设计模式-桥模式
将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
2024-11-24 14:48:19
650
原创 C++设计模式-装饰器模式
动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)。
2024-11-24 14:23:42
407
原创 C++设计模式-观察者模式
定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知,目标对象对此一无所知。Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。
2024-11-24 13:37:40
176
原创 C++设计模式-策略模式-StrategyMethod
定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。
2024-11-24 13:15:10
551
原创 C++设计模式-模板模式,Template Method
定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的某些特定步骤。Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
2024-11-24 12:51:17
349
原创 设计模式简介
软件中面临的挑战来自于变化,如各种业务的变化导致我们去不停的修改软件。设计模式就是解决变化的问题,但是要明确的是,设计模式不是让变化消失,而是缩小变化的范围,如一只小猫在满屋子乱跑,会搞得满屋子都很混乱,但是如果将猫关在笼子里,那么混乱只会发生在笼子里,所以设计模式的核心就是把变化关在笼子里,不让变化漫延的到处都是,就可谓好的代码,好的设计。编译时依赖->运行时依赖。
2024-11-24 12:32:35
422
原创 shared_ptr大小与线程安全
std::shared_ptr只有两个指针数据成员,sizeof(std::shared_ptr)=16,一个是Ptr裸指针在x64上是8字节,另外一个是_Ref_count_base对象的指针是8字节。两个加起来16字节。该对象有两个成员_Uses和_Weaks。这个对象是在std::make_shared时候创建的,可以在源码中查看到。控制块的操作是原子操作,是线程安全的,但是管理的数据对象本身的操作一般不是线程安全的。
2024-08-29 22:08:46
212
原创 记录智能指针和string使用中发现的问题
在c++11中,想要智能指针指向数组,需要这样写intint注意两个shared_ptr和unique_ptr的模板参数不同。但是只有这样写在c++11中才能编译通过。但是在c++11 中, shared_ptr这种写法是有问题的。但是unique_ptr这种做法是正确的。因为shared_ptr的默认删除器是delete,指向数组时模板参数依然是单个元素类型,所以析构会调用delete 而不是delete[], 造成内存或资源泄露解决办法:1:升级到c++17。
2023-02-09 00:02:18
181
原创 shell批量修改文件
批量修改文件名,有时在linux服务上还是会碰到的,最近笔者就碰到了,记录一下比如我想将所有文件后加上.bak, 可以这么做其中需要注意的是xrags -i 和{}, -i表示一种占位符,从管道读取到的参数会替换掉占位符,一般默认的就是{} ,-i表示使用占位符,也可以用-I(大写的i)指定其他的占位符,所以这行shell意思就很简单了。如果我们想恢复原来的文件名呢,可以这么做:需要注意的可能是两点,sed后面有个2g, 我们知道g表示全部替换,2g表示从第二个匹配项开始,因为第一个匹配项是1
2021-07-12 23:59:09
515
原创 c++一种反射机制,判断类中是否存在特定的函数
c++语言本身并没有提供反射机制,倒是有一个比较基础的RTTI,利用c++的模板特性,SFINAE,可以实现一些反射功能,先看代码:在这里插入代码片
2021-05-30 23:08:56
903
1
原创 C++ SFINAE和 enable_if
c++中的SFINAE和enable_if,如果经常写模板的话,应该听到看到这些东西.SFINAE首先介绍下SFINAE,参考官方介绍,中文是“模板替换失败不是一种错误”,看个代码示例class Test { using newType = int;};// 1template<typename T> void f(T arg) { cout<<"old type"<<endl;}// 2template <typename T>v
2021-05-30 18:14:58
240
原创 C++ 11 decltype 与auto
c++11 新特性中,用的比较多的应该是类型推导了,类型推导有两种,auto与decltype,先说说auto.1: autoauto在使用时,最需要注意的应该auto会去掉CV(const , volatile)属性与引用,细说的话有三种情况:1:auto 后没有引用或指针int a = 1;const int ca = 1;const int &caref = 1;auto a1 = a;auto a2 = ca;auto a3 = caref;template<ty
2021-05-19 00:33:51
142
原创 奇异递归模板模式
奇异递归模板模式(可参见wiki)在一般的编程中应该是不多见的,笔者在书籍上(陈硕的linux 服务器端开发 和more effective中有见过),后来在实际开发中没想到还真的碰到了,这个在元编程中应该还是比较常见的。template <class T> struct Base{ void interface() { // ... static_cast<T*>(this)->implementation();
2021-05-07 23:59:52
298
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人