自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(131)
  • 收藏
  • 关注

原创 trace-cmd记录线程被中断打断的时间

(3)执行任务过程中有内存操作,内存操作肯呢个引起缺页中断,用户同样的内存操作,有缺页中断和无缺页中断,所消耗的时间是不一样的。使用trace-cmd report可以查看监听结果,结果如下,通过结果进一步分析,我们就可以确定线程被中断打断的时间。(5)以上情况都没有,但是同样优先级的线程比较多,也就是系统负载比较高,这个线程的运行需要排队等待。(1)线程主动让出了cpu,比如线程中出现了sleep,使用了互斥体,等待io等。(2)线程被动让出cpu,线程被更高优先级的线程抢占。

2025-09-11 21:21:59 444

原创 xdp 入门

xdp 全称 eXpress Data Path,是 linux ebpf 中的一个功能。ebpf 在内核中预留了一些插入点,用户可以在这些插入点插入自己的处理逻辑,当数据路过插入点时可以做一些预期的处理,具体实现方式如下:① 用户编写数据处理代码,也就是对于路过这个插入点的数据想做什么处理② 将代码编译③ 将编译好的目标文件安装到插入点安装之后,数据路过插入点时便会被安装的代码处理。插入点的处理逻辑就像一些路口的收费站,不同身份的车辆通过收费站的时候,可能需要做不同的事情。

2024-02-28 18:08:19 5733

原创 linux下怎么定位内存泄漏

正常情况下,软件使用的内存是随着时间在一定范围内波动的。内存泄漏说的是随着时间的推移,进程使用的内存越来越多。一般情况下,内存泄漏是程序不断地申请内存,但是没有释放导致的。

2024-02-27 14:55:33 4129

原创 使用cgroup踩过的坑

cgroup 全称 control group,控制组。通过 cgroup 可以限制应用使用的资源,资源包括 cpu、内存、磁盘 io、网络等。工作中经常使用的 docker 容器就使用了 cgroup 进行资源限制和隔离,cgroup 是 docker 的基础。

2024-02-18 22:08:43 7918

原创 SCHED_FIFO 和 SCHED_RR 同时存在时,如何调度

(1)从上边的实验现象可以看出来,实验现象符合 SCHED_FIFO 先入先出,SCHED_RR 时间轮询的调度原理。(2)在实时调度策略中,高优先级具有绝对的优先调度的的特权,即使 SCHED_RR 这种时间片轮询的调度算法,也是说的多个 SCHED_RR 的优先级相等的前提下才会轮询,如果优先级不相等,那么只会调度优先级最高的那个线程。

2024-01-19 21:03:55 3578 1

原创 linux 中进程的 D 状态和 Z 状态

僵尸态是 linux 进程的一种状态,用 Z (zombie) 表示。处于 Z 状态的进程已经不在工作,进程的资源(内存,打开的文件) 都已经释放,只保留 struct task_struct 一个空壳子,用僵尸来表示这个状态非常形象。僵尸进程不能被信号杀死(因为僵尸进程已经死了,当然也不能响应信号),只能被父进程回收。进程处于僵尸态时保存的信息非常少,其中包括进程号,退出码,退出码是比较重要的,父进程回收僵尸进程的时候可以根据退出码确定子进程的退出原因。

2024-01-13 11:05:54 7356 1

原创 linux中fd的几点理解——一切皆文件

fd 全称是 file descriptor,文件描述符,又称句柄。当我们在打开一个文件,创建一个 socket, 创建一个 epoll 时,返回值往往都用一个变量 int fd 来表示。

2024-01-13 10:35:03 5591 1

原创 Fast DDS builtin_transports_reception_threads配置不生效原因分析

..//!见。该字段也参与。

2026-11-06 12:52:14 108

原创 fastdds:qos使用顺序

(1)要想使用if (!

2026-11-01 10:13:34 191

原创 分治算法题目记录

不了解分治算法,但是实际中已经使用分治算法了。分治算法,就是将一个问题拆分,将数据结构拆分,拆分成几份,每一份各自计算,然后再汇总结果。二分法是典型的分治算法,也是分治算法的基本思想,将数据结构分成两份,两份分别完成自己的工作。快速排序也属于分治算法,将数据分成左右两侧,分别排序。链表排序也属于分治算法,也属于归并算法,归并算法就是器皿中额很多小水珠,逐渐合并成一个大水珠的过程。可以直接从微观到宏观进行归并,也可以采用递归算法进行归并,递归算法更好理解,把每一半归并完,最大的两半再归并。

2026-10-06 14:58:45 608

原创 fastdds:flow controller

data writer是同步发送方式,可靠性qos是reliable,第一次发送通过同步方式发送,如果需要重传,则重传通过异步方式发送。data writer是同步发送模式,可靠性qos是best effort。flow controller是属于participant的资源。(2)如果是异步发送,还可以控制数据发送的带宽。data writer是异步发送模式。(1)纯同步(pure sync)(1)数据同步发送还是异步发送。(2)纯异步(async)(3)同步(sync)

2026-06-25 21:53:54 329

原创 fastdds:qos profile

fastdds中的domain participant、topic、publisher、subscriber、data writer、data reader均可以设置qos。qos几乎是dds配置的代名词了,所有的配置都在qos中。设置qos,可以在代码中指定,也可以通过xml格式的配置文件来指定。如下是HistoryQosPolicy的配置方式:代码:xml:<topic></topic>

2026-06-25 21:46:39 187

原创 使用实时调度策略和无锁队列踩坑记录

那么我们想一种场景,有3个线程,t1、t2、t3,t1的调度策略为SCHED_FIFO、优先级为1,t2的调度策略为SCHED_FIFO、优先级为2,t3的调度策略为SCHED_NORMAL,那么t2优先于t1被调度,t1优先于t3被调度。而实时调度策略,优先级高的又比优先级低的线程被优先调度。一般情况下,我们会认为try_push中会判断有没有剩余空间来盛放新的元素,如果有,那么就push成功,如果没有就通过返回值来标记,没有空间了,push失败,线程并不会在try_push内部陷入死循环;

2026-06-15 22:33:39 311

原创 tcp报文什么时候会真正发送

当用户使用tcp socket发送数据时,数据会立即被发送吗?不一定,tcp报文真正的发送由内核来定。那么满足什么条件的时候,tcp报文才会真正被发送?用户调用tcp socket的send函数,在内核调用tcp_sendmsg进入tcp协议栈,tcp协议栈的出口是tcp_transmit_skb,通过该函数将报文发送给ip层。讨论tcp报文什么时候会真正发送,先看一下有哪些条件会导致tcp报文不会被发送,当这些条件都不满足的时候,那么tcp就会被真正发送。

2026-04-11 21:11:48 402

原创 fastdds:wait-set

读取数据的方式有两种:Listener和Wait-set。Listener方式,使用简单,参考fastdds example中的hello_world,创建一个DataReaderListener的派生类,实现对应的虚函数;创建data reader的时候将这个对象当做listener的实参进行传递即可。这样当有DataWriter match的时候或者有数据到来的时候就,对应的回调函数就可以被调用到。

2026-02-26 19:23:52 995

原创 SOA面向服务架构

SOA即面向服务架构。当看到面向xxx的时候,我们很熟悉,讨论c++编程语言时,说c++是面向对象的编程语言。面相对象,那么对象作为一个基础的、核心的的概念,是c++的核心,c++中的概念都围绕着对象展开:类、抽象类、封装、继承、多态、模板等。那么对于SOA架构来说,则所有的概念都围绕着服务展开。AP AUTOSAR标准基于SOA范式实现了通信模块(),实现了面向服务的通信SOC(Service-Oriented Communication)。本文以AP AUTOSAR(

2026-02-25 16:04:41 1058

原创 linuxptp时间同步

让不同机器上的时间,保持一致,就是时间同步。多台机器下的任务需要在一个时间基准下工作,就需要时间同步。本文讨论的时间同步协议是PTP。时间同步在自动驾驶领域是至关重要的核心技术,其重要性不亚于传感器硬件和算法本身。它如同整个系统的“神经系统时钟”,确保各个部分协调一致地工作。自动驾驶汽车依赖激光雷达、摄像头、毫米波雷达、惯性导航单元等多种传感器。这些传感器以不同的频率(如10Hz、50Hz、100Hz)采集数据。

2026-01-25 21:03:24 986

原创 rust入门

什么是所有权,拥有什么?资源被哪个变量拥有。1、移动赋值在c++中,这样的操作是拷贝构造;而在rust中,这样会移动。c++默认情况下给了程序员最大的自由度,而rust正好相反。// 所有权从s1移动到s2,s1已经是无效的了,不能再使用对于基本数据类型,整型、浮点型、bool、char等,数据保存到栈上,默认支持Copy语义,赋值操作执行的是拷贝,而不是移动。println!2、调用函数①值传递,与赋值类似,也是会转移所有权。

2026-01-22 21:50:27 735

原创 malloc arena、mlock、mallopt

多线程应用中,并发调用malloc,malloc的实现中,多线程之间需要锁进行同步吗?大部分时候是不需要的。每个线程有自己的tcache,有自己的arena,有自己的堆。所以说,对于多线程的进程来说,多个线程有自己的堆,而不是共用一个堆。glibc中的malloc管理,为了减小多线程之间并发调用malloc时的同步,引入了arena和tcache。

2026-01-10 10:44:10 1073

原创 fastdds:DataWriter和DataReader匹配规则

本文通过fastdds中的函数EDP::valid_matching来了解相关的qos策略。在函数EDP::valid_matching中,会对DataReader和DataWriter的各种属性进行匹配性判断,当所有条件均满足时,DataReader和DataWriter才能相互发现;否则,两者不能相互发现。

2026-01-09 22:41:08 868

原创 n皇后问题

(2)每列放的时候,需要从上到下遍历这一列的哪个位置能放。(3)判断当前这个位置能不能放的个函数,抽象出来。(4)都放完之后,就是一个结果。(1)每列需要放一个。

2025-12-07 21:02:55 216

原创 滑动窗口问题记录

对于字符串或者数组,找到一个连续的区间,这个区间满足一定的条件。这样的问题就使用滑动窗口来解决,滑动窗口,从某种意义上属于动态规划算法,也使用了双指针。滑动窗口的关键是确定窗口的两个边沿什么时候移动,什么条件下移动。一般情况下,窗口右边沿是一直向前移动,在移动的过程中根据判断条件来决定左边沿是不是需要移动。

2025-12-07 20:11:33 307

原创 c++虚函数及常见问题

封装,抽象,继承,多态是面向对象编程语言的特点。个人认为抽象和继承都是手段,多态才是目标,继承是多态的基础。(1)将属性和函数封装到一个类里边,属性和函数组成一个完整的对象(2)权限管理,public, private, protected, 增强安全性(3)暴露有限的接口,增强了易用性,增强了安全性(1)抽象这个概念存在于很多场景,我们使用函数,本身就是通过函数隐藏具体的实现细节,这也算抽象(2)c++ 中的抽象,可以使用抽象类来认识,抽象类是包含纯虚函数的类,抽象类不能创建对象。

2025-11-29 12:28:23 1253

原创 c语言:double a = 3 / 2,a等于多少

e和f的区别:f中将a转换为了double类型,这样表达式就一个数据时double一个是int,表达式的类型就转换为了double;c = a/b这样是一个表达式,但是在计算a/b的是时候a/b本身也是一个表达式,这个表达式中都是int数据类型,也就不会转换成浮点类型。c语言中不同类型的数据进行计算,会进行默认类型转换,转换的原则是向精度高的方向转换,这样能保证不丢失精度。表达式的数据类型要转换成精度最高的那个数据类型的精度,这点没问题,但是要区分表达式的边界。那么下边的代码,c、d、e、f分别是什么?

2025-11-16 12:09:59 263

原创 编译动态库时只需要知道函数的声明,与可执行文件不同

通过g++ -fPIC -shared -o libhello.so lib.c编译动态库,可以编译成功,编译过程并不会去找构造函数Hello和Say函数的实现。main.c:包含了hello.h头文件,并且创建了Hello,执行了Say函数。lib.c:包含了hello.h头文件,并且创建了Hello,执行了Say函数。在编译动态库的时候,不需要知道函数的实现,只需要知道函数的声明就可以。hello.c:类的实现,定义了Hello构造函数和Say函数的实现。编译可执行文件的时候,需要知道函数的实现。

2025-11-15 20:34:49 167

原创 fastdds qos:UserDataQosPolicy

需要继承DomainParticipantListener,并实现on_paricipant_discovery,on_data_reader_discovery,on_data_writer_discovery三个函数。②创建DomainParicipant时需要传this指针,并且status_mask,要设置data avaliable,否则DataReader无法订阅到数据。DmainParticipant,DataWriter,DataReader读可以设置user data。

2025-11-02 17:03:19 243

原创 架构设计常画哪些图

在架构设计时,经常需要画图。在大多数时候,我们工作的团队并没有对架构设计中的图做规定,只要能把架构表达清楚即可,对于比较简单的软件,甚至不需要画图,只使用文字就可以描述清楚。这种因人而异的画图方式,比较灵活,并且效率高,用较少的图就能表达较多的信息,一张图中既能表达静态信息,又能表达动态信息,但是不利于跨团队之间的合作(很多时候也不需要跨团队合作,当然也没有问题)。当需要跨团队合作,或者多个人协同开发的时候,统一画图标准,往往就比较重要。

2025-10-08 17:27:15 827

原创 c++:std::string,std::function,std::vector隐式申请动态内存

①如下代码,声明一个局部std::string变量s,打印出来s的capaciy为15,也就是说,默认情况下,std::string能保存15个字符,不需要动态申请内存(对malloc设置断点,没有打断,说明没有动态申请内存)。②向s赋值一个长度为15的字符串,不会申请动态内存。③向s赋值一个长度为16的字符串,会申请动态内存,会调用malloc。

2025-10-01 09:54:32 358

原创 设计模式:观察者模式

我们在开发中经常使用回调函数的思想,想要观察一个对象的状态变化,就向该对象注册一个回调函数,当对象状态变化的时候,调用注册的回调函数。如果有多个观察者呢,注册的回调函数就可以放到数组中,当对象状态变化的时候,依次调用数组中的回调函数。当然也可以实现一个观察者接口,每个观察者都实现接口,创建一个观察者对象,然后将对象注册给被观察者。当被观察者状态发生变化时,逐个调用观察者的函数。观察者模式,关键自是观察者,Observer。微信群、钉钉群,当有人在群里发送信息时,每个读者都是观察者,发消息的人是被观察者。

2025-09-13 19:46:37 202

原创 linux下timerfd和posix timer为什么存在较大的抖动?

在linux中开发引用,timerfd和posix timer是最常用的定时器。timerfd是linux特有的定时器,通过fd来实现定时器,体现了linux"一切皆文件"的思想;posix timer,只要符合posix标准的操作系统,均应支持。在开发确定性应用时,需要选用确定性的定时器。搜索网络上的一些资料,往往说这两种定时器的精度可以达到纳秒级。但是在实际测试中,尤其是在压测时,即使linux打了实时补丁,两种定时器的抖动也会比较大,可以达到700μs,甚至更大。

2025-09-13 15:32:06 1264

原创 linux线程被中断打断,不会计入调度次数

通过线程的status文件,可以查看线程的调度次数。status的最后两行,voluntary_ctxt_switches表示线程的资源调度次数,比如线程调用了sleep睡眠,或者调用io接口发生了阻塞,均会统计为主动调度次数;nonvoluntary_ctxt_switches表示非自愿调度次数,比如线程在运行过程中被强张了。

2025-09-11 21:21:37 386

原创 fastdds qos:LifespanQosPolicy

在实际业务中,如果对数据的新/旧程度有要求,比如数据产生之后如果1ms都没有被使用,那么数据就相当于过期了,没有使用价值了,这种数据直接丢弃就可以了。如果有这种需求,那么可以考虑结合LifespanQosPolicy来实现。通过helloworld进行测试,将超时时间设置的非常短100ns,实际测试可以看到DataReader接收不到DataWriter发送的数据。(1)当DataWriter写数据History的数据,或者接收数据到DataReader的History的数据,均可以加时间戳。

2025-08-30 18:42:16 395

原创 tcp会无限次重传吗

超过这个次数,tcp会放弃重传,然后通过函数tcp_write_err将套接字的状态置错误。socket状态置为错误之后,针对这个socket的阻塞调用,比如read,epoll_wait等便会返回,但是返回值表示错误。tcp作为面向连接的,可靠的,字节流。最终要的特点就是可靠,其中重传又是保证可靠的重要前提。那么当tcp发送数据之后,收不到ack的情况下,会无限次重传吗。超过这个次数,tcp会将信息报告给网络层,网络层会进行一些操作,比如缓存的更新等。在建立连接的阶段,syn报文的重传次数。

2025-08-17 20:50:47 400

原创 fastdds:默认qos

Publisher、Subscriber、DataWriter、DataReader、Topic均可以应用qos策略,不同的qos策略的使用范围是不一样的:DeadelineQosPolicy适用于Topic、DataWriter、DataReader;具体每种策略的适用范围,可以看官方文档的描述,也可以看fastdds源码,以TopicQos为例,源码中唵TopicQos类来管理,其中的汽油成员如下,说明这些qos策略适用于qos。(3)qos策略需要匹配,通信的双方才能通信。(2)qos策略适用对象。

2025-07-23 21:58:42 624

原创 c++无锁队列moodycamel::ConcurrentQueue测试结果

在c++开发中,无锁队列moodycamel::ConcurrentQueue使用较多,示意图如下:从宏观来看moodycamel::ConcurrentQueue是MPMC队列,即多生产者,多消费者队列;从微观来看,是SPMC队列,即单生产者,多消费者队列。在ConcurrentQueue中,没个生产者都有自己对应的队列。这也引入了ConcurrentQueue的一个特点:ConcurrentQueue只能保证单个生产者的FIFO特性,即对于一个生产者来说,元素出队的顺序和入队的顺序是一样的。

2025-07-13 13:40:23 1126

原创 leetcode:最小覆盖字符串

对于算法题目,自己能想到的往往是最基础的笨方法。代码如下:如果t的长度是len1,s的长度是len2,那么最小窗口是len1,最大窗口是len2。所以可以从len1到len2,遍历窗口大小,对于每个窗口大小,将窗口从前向后进行移动。因为窗口是从小到大进行遍历,所以第一次遇到满足条件的子串时,就可以直接范围。这种算法的时间复杂度是O(n*n),在leetcode上运行会超时。

2025-05-04 18:44:30 605

原创 递归下降算法

在软件开发中有这样一个需求,开发语言是c++,用户可以通过配置指定任务依赖的事件,比如配置e1|e2|e3的意思是,e1、e2、e3 3个事件,只要有一个到来,那么条件就是满足的,任务可以执行;在比如,用户还可以配置(2*e1 | e2) & e3,这样复杂的逻辑,表示e3是必要的,另外e1到来两次或者e2到来一次也是必要的。事件的个数不仅仅是3个,还可以更多,逻辑关系包含|表示或,&表示与,*表示时间到来的次数,逻辑关系可以任意组合。之前只听说和使用过递归算法,递归算法就是在函数内部调用函数本身。

2025-05-04 18:15:41 417

原创 uml类关系(实现、继承,聚合、组合,依赖、关联)

drawio和EA是架构设计时经常使用的画图工具。drawio学习门槛低,使用灵活,但是功能仅仅限于画图。EA学习门槛高,但是功能更加的丰富:①在画图方面,EA严格满足UML标准,EA中的图和类是关联的,如果修改了一个类的名字或者函数等,在引用这个类的图中也会自动修改②EA还可以将架构设计时定义的类、接口等导出为代码③EA可以导入已有的代码,生成类图。

2025-04-26 17:40:21 1364

原创 fastdds:传输层SHM和DATA-SHARING的区别

下图是fastdds官方的图,清晰地展示了dds支持的传输层:根据通信双方的相对位置(跨机器、同机器跨进程、同进程)的不同选择合适的传输层,是通信中间件必须要考虑的事情。跨机器通信,只能通过网络, fastdds支持UDP和TCP。在同一个机器中,使用UDP和TCP进行通信,当然也是可以的。但是,从性能的角度来考虑,更推荐使用SHM,SHM和UDP/TCP相比有2点优势:1、减少系统调用次数共享内存创建完成之后,后边使用的时候直接是内存操作,而UCP/TCP每次发送或者接收的的时候,都要通过系统调用。

2025-04-18 21:37:23 1933

原创 fastdds:传输层端口号计算规则

假如A发布的多播消息,那么B和C都会收到,如果B和A之间有相同topic的writer和reader,也就是说B和A是可以通信的,那么B就会向A发送单播消息,进行后续的协商,后边的协商过程均通过单播来实现。participantId的分配如下代码所示,同一个进程的同一个domain内,participantId都是从0开始的,也就是说participantId并不是domain内唯一的,而是domain和进程内唯一的。同样的,如果单播端口已经被占用,那么就会进行重试,重试的算法是在上一个端口的基础上加2。

2025-03-30 20:25:07 1509

fastdds ack nack

fastdds ack nack

2026-10-04

linuxptp时间同步

linuxptp时间同步

2026-08-16

文心快码:写一个通过tcp进行通信的功能

文心快码:写一个通过tcp进行通信的功能

2026-03-13

空空如也

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

TA关注的人

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