自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(123)
  • 问答 (1)
  • 收藏
  • 关注

原创 关于os进程

PID为0的是调度进程,该进程是内核的一部分,也称为系统进程;PID为1的进程为init进程,它是一个普通的用户进程,但是以超级用户特权运行;PID为2的进程是页守护进程,负责支持虚拟存储系统的分页操作。系统用PCB来描述进程的基本情况和活动过程,从而控制和管理进程。由程序段、相关数据段和PCB三部分构成进程的实体,一般简称为进程。所谓创建进程就是创建进程实体中的PCB,而撤销进程也就是撤销进程的PCB。PCB包含信息:1、进程状态(state);2、进程标识信息(uid、gid);

2024-03-09 16:57:11 369

原创 构造函数不能声明为虚函数

构造函数的调用是静态绑定的,即在编译时确定的,而不是动态绑定的,因此构造函数不能是虚函数。因为在对象构造过程中,虚函数表还没有被构造完毕,无法实现动态绑定的特性。

2024-03-09 15:55:44 376

原创 网络包收包DMA中断处理流程

这个整个过程保证了从网络包通过DMA传输到中断处理再到网络协议栈处理和应用程序中的处理,确保了网络数据包的正确接收和处理。DMA的使用减轻了CPU的负担,提高了数据包的传输效率,而中断机制则保证了数据包能够及时地被处理。这个过程中,网卡的硬件负责将数据包从网卡的接收缓冲区中复制到系统内存中的预先分配好的接收缓冲区中。中断触发:一旦DMA传输完成,网卡将会触发一个中断,通知CPU有新的数据包已经被成功接收并存储到内存中。传输到应用程序:经过网络协议栈处理后,数据包将被传递到适当的应用程序中进行处理。

2024-02-26 20:06:29 398

原创 netfilter内核实现

钩子函数(Hooks):Netfilter框架在Linux内核中通过钩子函数实现数据包的过滤和处理。这些API包括针对规则表和连接追踪表的操作接口,允许用户空间程序配置、监控和操作网络功能。Netfilter是Linux内核中的一个框架,用于实现数据包的过滤、NAT(Network Address Translation)、连接追踪以及其他网络功能。总的来说,Netfilter的实现是通过在Linux内核中实现钩子函数、数据结构和API接口,以实现对数据包的处理和网络功能的扩展和定制。

2024-02-26 20:01:04 406

原创 epoll ET模式怎么保证可靠性

确保读和写操作完整性:在使用ET模式时,需要确保每次读取或写入的数据是完整的,这可以通过循环读取或写入直到返回EAGAIN错误来实现。处理边缘触发事件:ET模式下,只有当文件描述符状态发生变化时才会触发事件通知,因此需要及时处理边缘触发事件,确保不会错过任何事件。使用非阻塞IO:通过设置文件描述符为非阻塞模式,可以确保epoll在ET模式下能够及时地收到事件通知。处理错误情况:在ET模式下,需要及时处理错误事件,例如读写超时、连接被重置等情况,以确保程序的可靠性。

2024-02-26 19:56:26 355

原创 c++11支持使用范围初始化的容器

unordered_map需要用pair初始化。

2024-02-24 16:01:57 302

转载 蓝牙协议入门

https://wrlus.com/wireless-security/bluetooth-intro/

2024-02-08 11:20:33 21

原创 指向派生类的基类指针、强转为 void* 再转为基类指针、此时调用虚函数会发生什么(正常)?

3,调用虚函数:如果这个基类中的虚函数在派生类中被覆盖(override),那么在运行时,由于编译器在转换回基类指针时假定这个指针指向的是基类对象,因此调用虚函数时会根据基类的虚函数表来确定调用哪个函数。这意味着即使实际上这个指针指向的是派生类对象,也会调用基类中的虚函数实现,而不是派生类中的实现。类型的指针转换回基类指针时,编译器会进行一次静态类型转换。这意味着编译器会假定这个指针是指向基类对象的,而不考虑它原本指向派生类对象。类型时,指针的类型信息会丢失,但指针仍然指向原来的对象。

2024-02-08 10:16:51 368

原创 子类将基类的虚函数替换为其自己的虚函数,共用的一个虚函数表,怎么不影响基类

如果该指针指向一个派生类对象,那么派生类的虚函数地址就会被调用,而如果指向一个基类对象,那么基类的虚函数地址就会被调用,这个过程与实际的虚函数表是如何维护无关。如果派生类对虚函数进行了重新定义,那么它会生成一个新的子类虚函数表,并且把不同的虚函数地址填入其中,从而覆盖了基类虚函数表中对应的虚函数地址。每个类对象都含有一个指向其虚函数表的指针,实际上,这个指针指向的是该类的虚函数表,也就是说,所有该类对象的虚函数指针指向该虚函数表。所以,操作派生类对象不会污染基类的虚函数表,它们之间的虚函数是完全独立的。

2024-02-08 10:12:41 327

原创 C++多态,父类有virtual, 子类继承时, 会拷贝父类的虚函数表吗

子类的虚函数表会继承父类的虚函数表,并添加自己新增的虚函数。在 C++ 中,在父类中声明的虚函数会在子类中被继承,并且子类中所生成的对象如果重写了父类中的虚函数,其虚函数表将被更新以指向重写后的函数地址。因此,子类不需要再次拷贝一份父类的虚函数表,可以直接继承父类的虚函数表。如果子类覆盖了父类的虚函数,则子类的虚函数表会被更新,以指向重写后的函数地址,而不是父类的函数地址。因此,子类不需要拷贝一份父类的虚函数表,虚函数表的继承和更新是由编译器完成的。

2024-02-07 16:29:20 315

原创 std::function与回调函数的区别

同时std::function也更加通用,你可以用其存储任何可以被调用的对象(callable object),只要有正确的函数签名即可。利用std::function你不但可以保存一段代码,同时也可以保存必要的上下文,然后在合适的地方基于上下文调用这段代码。,这里的上下文就是指代码依赖的数据,你不得不自己动手构造出一个结构体用来存储代码依赖的上下文。std::function的作用本质上和我们刚才定义的结构体区别不大。,就是因为函数指针没有办法捕捉this(指向对象的指针)这个上下文。

2024-02-07 14:36:21 378

原创 c++main函数之前程序会做什么?

初始化静态存储区:全局变量和静态变量存储在程序的静态存储区,在程序开始执行之前,这些变量会被初始化为默认值(如果有的话)或者指定的初值。执行操作系统特定的初始化工作:操作系统可能会做一些与平台相关的初始化工作,例如设置信号处理器、初始化文件系统等。初始化运行时环境:运行时环境的初始化包括初始化 C++ 运行时库和一些全局状态,例如堆栈指针的设置等。加载程序到内存:操作系统会将程序的可执行文件加载到内存中,并分配相应的资源。设置程序的入口点:操作系统会将程序的执行控制权交给程序的入口点,即。

2024-01-18 16:37:42 398

原创 服务器大量time_wait影响性能,如何解决

使用连接池:对于需要频繁连接数据库或者其他服务的应用程序,可以考虑使用连接池技术,减少连接的建立和关闭次数,从而减少 TIME_WAIT 状态连接的数量。优化应用程序:如果可能的话,可以优化应用程序的设计和实现,减少连接的建立和关闭次数,从而减少 TIME_WAIT 状态连接的数量。调整连接超时时间:可以调整操作系统的 TCP 连接超时时间,减少 TIME_WAIT 状态的持续时间。调整内核参数:可以通过修改操作系统的内核参数来调整 TIME_WAIT 状态的处理。

2024-01-18 11:35:53 518

原创 redis为什么快

数据结构多样性:Redis 提供了丰富的数据结构,如字符串、列表、哈希表、集合、有序集合等,每种数据结构都有专门的命令和优化策略,可以满足不同场景的需求,提高了数据的存储和访问效率。高效的网络通信协议:Redis 使用自定义的 RESP(REdis Serialization Protocol)协议进行客户端和服务器之间的通信,该协议简单高效,减少了通信开销。持久化可以将数据写入磁盘,保证数据的可靠性,但默认情况下 Redis 只在内存中操作,避免了磁盘 I/O 的性能开销。

2024-01-18 11:32:31 769

原创 进程切换的开销为什么比线程更大

进程有独立的地址空间,进程切换时需要切换地址空间的映射关系,这涉及到页表的切换和 TLB(Translation Lookaside Buffer)的刷新等操作,开销较大。由于进程具有独立的地址空间和资源,进程切换需要考虑安全性和隔离性,例如需要刷新 TLB、清理缓存等,增加了切换的开销。线程切换只需要保存和恢复线程的上下文信息,相对于进程来说,线程的上下文信息更少,因此线程切换的开销较小。进程有独立的资源,包括文件描述符、打开的文件、信号处理器等,进程切换时需要切换和管理这些资源,开销较大。

2024-01-18 11:17:32 684

原创 lambda为什么能提升处理性能

减少函数调用开销:Lambda 表示式通常用于 STL 中的算法、并发编程中的任务等,这些场景中往往需要频繁地调用函数来处理数据。Lambda 表示式可以直接在函数中定义匿名函数,避免了函数调用的开销,从而提高了程序的运行效率。例如,编译器可以使用常量折叠、死代码消除等技术来消除一些不必要的计算,从而提高程序的执行效率。并行编程可以利用多核处理器的性能优势,提高程序的执行效率。Lambda 表示式是 C++ 11 中新增的一种函数对象,它可以在一个函数内部定义匿名函数,并将其作为函数的参数或返回值传递。

2024-01-12 01:15:01 419

原创 nginx怎么把http握手包返回请求方

有3个http请求,分别是A,B,C 握手包发出后,反向代理的nginx怎么返回到对应的请求。答案:nginx为每个请求生成一个唯一标识符request_id,保存在nginx内存中。

2024-01-11 10:37:06 333

原创 某一线大厂爱问的装X问题

如果是hash表解决,因为数据量太大,又想在内存中高速处理,显然内存装不下。海量数据,超过单机内存,怎么快速判断在某集合中,不能进行I/O。只能通过bloom filter解决,原理网上很多。

2024-01-11 10:31:12 383

原创 vector map迭代器失效问题

对于vector来说,如果使用普通迭代器(例如std::vector<int>::iterator)进行遍历和删除操作,当你删除一个元素后,后面的元素会向前移动填补空缺,导致当前迭代器指向的位置已经不再有效。因为在删除某个键值对后,其他键值对的位置可能发生变化,导致当前迭代器无法正确指向下一个要访问的元素。注意:C++11 引入了范围循环 for-each,但不适用于在迭代过程中删除元素的情况,因为它使用的是临时迭代器并不允许修改容器。当使用迭代器遍历容器并删除元素时,迭代器可能会失效。

2024-01-10 11:15:28 399

原创 超过varchar最大长度会怎样

varchar最大长度65535,超过会强制转为text类型。

2024-01-08 21:15:36 395

转载 关于TIME_WAIT

https://www.jianshu.com/p/63460b962f2c

2024-01-08 20:17:57 26

原创 为什么线程挂掉会影响其他线程?

线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,是共享地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些.

2024-01-08 19:50:57 405

原创 2pc和3pc的区别

与 2PC 协议相比,3PC 协议将 CanCommit 阶段(询问阶段)添加到协议中,使参与者能够在 CanCommit 阶段发现并解决可能导致阻塞的问题。这样,3PC 协议能够更快地执行提交或回滚事务,并减少不必要的等待时间。需要注意的是,与 2PC 协议相比,3PC 协议仍然可能存在阻塞的问题。

2024-01-08 15:47:21 339

原创 进程A和进程B都处于用户态能相互通信吗?

因为进程A和进程B的虚拟地址空间(0-3GB)需要进行地址映射,映射后进程A和进程B访问的物理内存不是同一块内存,所以进程A和进程B无法在用户态通信。内核地址空间是直接映射,所以进程A和进程B能通过相同的虚拟地址空间访问物理内存,进程A和进程B实现通信就有了理论依据。既然用户态无法通信,所以我们只能想另外的办法,我们把进程切换到内核态,看一下进程A和进程B是否能通信。因为直接映射的这个机制,所有的进程的内核空间都指向同一块物理内存,所有进程共享内核代码段和数据段。

2024-01-08 09:08:19 485

原创 返回数字字符串所有有效IP地址

使用一个循环来尝试不同长度的整数,同时确保整数的值在 0 到 255 之间。例如,如果以 0 开头的整数只能是 0,不能是 01 或 001 等。作为输入,并返回一个字符串向量,表示所有可能的有效 IP 地址。,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在。如果已经遍历完整个字符串,并且已经找到了 4 个整数,则将结果加入到结果集中。如果剩余字符数太多或太少,无法凑成一个 IP 地址,则不再继续搜索。这个算法的时间复杂度是 O(1),因为 IP 地址的长度是固定的。

2024-01-04 09:14:22 370

原创 Proactor和Reactor区别

需要注意的是,这里所属的非阻塞是指使用的socket是非阻塞的,但是用户进程依然是阻塞的,与前面的分析并不冲突,在每次感知到有事件发生(比如可读就绪事件)后,就需要应用进程主动调用 read 方法来完成数据的读取,也就是要应用进程主动将 socket 接收缓存中的数据读到应用进程内存中,这个过程是同步的,读取完数据后应用进程才能处理数据。因此,Reactor 可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而 Proactor 可以理解为「来了事件操作系统来处理,处理完再通知应用进程」。

2023-12-27 16:43:45 392

原创 分布式一致性算法

paxos,raft,ZAB,gossip

2023-12-15 14:33:51 383

原创 迭代器失效及解决办法

对于vector来说,如果使用普通迭代器(例如std::vector<int>::iterator)进行遍历和删除操作,当你删除一个元素后,后面的元素会向前移动填补空缺,导致当前迭代器指向的位置已经不再有效。因为在删除某个键值对后,其他键值对的位置可能发生变化,导致当前迭代器无法正确指向下一个要访问的元素。注意:C++11 引入了范围循环 for-each,但不适用于在迭代过程中删除元素的情况,因为它使用的是临时迭代器并不允许修改容器。当使用迭代器遍历容器并删除元素时,迭代器可能会失效。

2023-12-09 12:44:53 531

原创 类的静态成员不可以在初始化列表初始化

/初始化静态的私有成员,尽管是私有的,但c++依然允许这样使用。//什么都不做的构造函数。//什么都不做的析构函数。

2023-12-04 21:25:03 423

原创 CRTP静态多态

最后,在main()函数中,创建了Derived1和Derived2的实例,并调用它们的foo()函数。在这个示例中,定义了一个模板类Base,模板类中包含函数foo_function(),并使用模板参数Derived作为类型参数。CRTP使用一个模板类作为基类,派生类中,使用基类的模板参数作为派生类的类型参数,从而实现了静态多态。由于使用了CRTP技术,因此在编译时就能够确定foo_function()函数的具体实现,从而避免了动态多态带来的运行时开销。

2023-11-25 16:52:55 450

原创 虚函数表结构

2023-11-25 16:39:08 347

原创 虚函数表生成时机&存储位置

动态多态:运行时多态,父类指针的指向,如果指向的是基类就去基类的虚函数表找相关函数接口,如果指向子类,就去子类的虚函数表找。(浅拷贝和深拷贝,浅拷贝时两个对象的虚函数指针相同,如果一个对象释放了,会导致另一个对象的虚函数表指针丢失)编译时,并不知道每个类会创建多少个对象,所以虚函数表是与类相关的,一个类对应一个虚函数表。3、继承时:如果没有重写,就会复制父类的,发生重写时,就将重写后的虚函数地址进行替换。不同对象的虚函数表指针不一样,但是指向的地址是一样的。.data:初始化的全局变量,静态变量。

2023-11-25 10:22:02 449

转载 std::copy性能为什么比for循环高

当我们对动态数组调用std::copy的时候,实际上就是调用的memmove的C标准库,用memmove可以加快复制过程

2022-07-27 21:08:56 603 1

原创 rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread) has assert failed at原因分析

rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread) has assert failed at

2022-06-24 16:24:22 2749

原创 蓝牙完整协议栈对照图

图片来自:传统蓝牙RFCOMM协议概念介绍-Bluetooth rfcomm_Wireless_Link的博客-CSDN博客_蓝牙rfcomm协议零. 概述本文章主要讲下蓝牙RFCOMM协议(bluetooth rfcomm)的概念以及在整个蓝牙协议栈中的起的作用一. 声明本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬..

2022-05-19 11:43:36 841

原创 fopen/fread对比open/read线程安全性分析

fopen,fread与open,read分别属于两套接口,open,read更偏底层属于系统调用在项目中用到了fopen,fread,fseek组合使用时,存在线程安全问题,需要加锁,也就是lock() //加锁fopenfseekfreadfcloseunlock() //解锁原因是每个线程fopen时都会有一条独立的IO流,但是这些IO流在底层缓存时存在线程安全的问题相比起来open,read接口组合使用时,就不存在线程安全的问题,已经测试过,不需要加锁...

2021-11-23 17:44:16 1581

原创 rtthread dcm组件dcm_cache_save接口mkdir:/data failed解决办法

项目中用到了了rtthread dcm 数据持久化组件,但是在dcm_cache_save时报mkdir:/data failed但是这个错误日志不是本项目的代码,经确认是dcm接口内部打印的日志然后确认了宏#define DCM_DEFAULT_STORAGE_NAME "/user/data/db/dcm" 在rtconfig.h中已经声明,同时业务代码在系统启动时也有用到该宏最后排查是因为dcm_default_storage_name在系统启动时需要赋值,dcm组件的dcm_strg

2021-11-09 16:23:48 375

原创 keil 编译链接时报错误代码L6286E解决办法

用网上很多办法没有解决最后,修改keil的编译选项为-O1解决问题我的keil版本是5.33 如下图所示

2021-11-01 21:21:54 1799

原创 librws是如何发送报文的------之rws_socket_connect详解

librws是小型跨平台websocket客户端C库因为分析rws_socket_send_text函数时,只看到时给socket结构体的的send_frames添加节点,没看到发送的代码,实在太疑惑,于是分析了下librws的代码,找到了原因下边分析下rws_socket_connect函数rws_socket_connect函数最后return rws_socket_create_start_work_thread此函数中会创建一个线程rws_socket_work_th_func.

2021-10-18 20:35:28 740 3

转载 RTThread工作队列详解

RT-Thread-RT-Thread workqueue 详解RT-Thread问答社区 - RT-Thread

2021-10-11 20:54:45 671

空空如也

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

TA关注的人

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