自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 为什么需要weak_ptr

当 a 和 b 的引用计数都降为 0 时,并不会释放资源,因为它们相互引用导致引用计数永远无法降为 0,从而导致内存泄漏。// 当 a 和 b 的引用计数都降为 0 时,会导致内存泄漏,因为它们相互引用导致引用计数永远无法降为 0。// A 拥有一个指向 B 的 shared_ptr。// B 拥有一个指向 A 的 shared_ptr。// A 持有 B 的 shared_ptr。// 在这里,释放 a 和 b 的 shared_ptr 引用。

2024-10-26 10:09:03 235

原创 c++const

const修饰指针时有两种情况。一种是指向常量的指针(const int *ptr或int const *ptr),表示指针指向的内容是常量,不能通过该指针修改指向的内容,但指针本身可以指向其他地址;另一种是指针本身是常量(int * const ptr),表示指针本身的值不能被修改,即指针只能指向初始化时指定的地址。

2024-09-12 15:32:12 446

原创 如何在RTOS中处理长时间运行的中断?

为了避免中断服务程序占用过多的CPU时间,通常将耗时的处理放到下半部执行,例如使用任务let或延迟任务。ISR只处理最基础的操作,然后通知系统的任务去完成更复杂的任务。

2024-09-09 20:11:56 409

原创 优先级继承如何实现

当一个线程与另一个线程有互斥关系时,高优先级线程可以继承低优先级线程的优先级,以确保高优先级线程能够在必要时快速执行。优先级继承:在RTThread中,继承优先级可以确保当一个线程等待另一个线程时,它的优先级会被提升为被等待线程的优先级。互斥锁:当一个线程获得了一个互斥锁并且等待另外一个线程时,RTThread会将等待线程的优先级提升到当前线程的优先级。通过这些机制,RTThread可以确保高优先级线程在需要时能够在低优先级线程之前执行,从而提高系统的实时性和响应性。

2024-09-09 19:47:33 405

原创 任务优先级反转是什么?如何解决?

任务优先级反转是指低优先级任务持有资源,高优先级任务等待该资源,但中等优先级任务抢占了低优先级任务的执行,导致高优先级任务无法执行。解决方法包括优先级继承机制,允许低优先级任务临时提升到高优先级。

2024-09-09 19:45:16 156

原创 弱网环境socket编程应对策略

**多线程或多进程处理**:可以利用并发编程,在不同线程或进程中处理数据接收与发送,保证即使在某个连接延迟严重的情况下,其他连接依然可以正常工作。- **本地缓存**:对于较大的数据传输,可以在发送前对数据进行分块并存储缓存,传输过程中记录进度,一旦出现断网或超时,可以从上次中断的地方继续传输。- **TCP自带的拥塞控制**:TCP协议有内建的拥塞控制机制,但在弱网环境下,可能仍需优化应用层的传输逻辑,避免过度发送数据导致网络堵塞。- **ACK机制**:通过发送确认包(ACK)确保数据的可靠传输。

2024-09-09 19:11:10 686

原创 协议层面优化a2dp性能

**优化低功耗模式切换**:在蓝牙协议栈中,针对A2DP传输,可以优化能量管理机制,使设备在闲置时能迅速进入低功耗模式,减少能量消耗。- **降低缓冲区延迟**:为了减少延迟,设备可以适当优化A2DP缓冲区的大小。- **多设备传输的智能调度**:如果设备同时连接多个蓝牙设备,可以通过协议层面的调度机制,优化数据传输的时间片分配,避免冲突,提高多设备同时使用时的传输效率。- **SBC(Subband Codec)**:A2DP的默认编解码器,兼容性最好,但在高音质要求下可能需要更多带宽。

2024-09-09 17:59:51 481

原创 Lambda表达式用作模板函数的参数

在这个示例中,ProcessData是一个模板函数,其中第二个参数Func是一个函数对象类型。在main函数中,我们创建一个Lambda表达式[](int x) { return x * 2;},并将其作为第二个参数传递给ProcessData模板函数。// 使用Lambda表达式调用模板函数。

2024-05-23 16:50:45 332

原创 函数重载和模板之间的区别

C++ 中的函数重载和模板之间最重要的区别之一是模板不能接受不同数量的参数,但重载函数可以接受不同数量的参数。

2024-05-20 20:13:52 160

原创 单链表如何删除当前节点?不从头遍历如何删除?

在单链表中,如果不从头遍历且只有当前节点的指针,通常的方法是将当前节点的下一个节点的数据复制到当前节点,然后删除当前节点的下一个节点。这种方法不适用于删除最后一个节点,因为它没有下一个节点的数据可以复制。如果需要删除的是最后一个节点,这种方法将失效,通常需要从头遍历来定位前一个节点来进行删除。

2024-05-18 10:15:19 405

原创 能不能定义一个std::string(“helloworld“)再返回其 c_str()?

不可以。这是因为当你创建一个局部的std::string对象并从函数中返回其c_str()时,std::string对象在函数返回后会被销毁,它的析构函数会释放其占用的内存。这将导致返回的const char*指针指向一块已经被释放的内存,从而产生悬挂指针和未定义行为。

2024-05-18 10:12:58 368

原创 如何理解移动语义的?移动一个int会不会将其置0?

对于基本数据类型,如int,实际上不存在“移动”的操作。int是一个简单的值类型,不涉及动态资源管理。移动一个int和复制它效果相同,都是简单的值复制。移动操作不会改变原始int值,也就是说,移动一个int并不会将其置为0。移动语义主要针对那些管理动态资源的复杂对象,对于简单的值类型并没有意义。

2024-05-18 10:10:57 395

原创 使用make_shared构造shared_ptr和先new再置入哪个好?好在哪?

在单个操作中分配内存,同时为对象和其引用计数分配空间,减少了一次内存分配和释放的开销。分配一块足够大的内存,用来存储对象本身和控制块(包括引用计数和弱引用计数)。在构造过程中可能因为异常导致内存泄露,而。在分配得到的内存上构造对象,构造控制块。避免了这个问题,因为它只有一个操作。能以更简洁的代码完成同样的工作。返回指向新构造对象的。

2024-05-18 10:07:58 467

原创 std::move一个const对象

类型,这意味着移动构造函数或移动赋值操作符无法应用于这个对象,因为它们通常要修改源对象,而。本身只是将对象的类型转换为右值引用,使得可以使用移动语义。对象的结果,通常会退化到使用拷贝构造或拷贝赋值,就像没有使用。修饰符强制性地从该对象中移除来实现,方法是使用。,即便转换为右值引用,依然会被视为。的语义,可能会引发未定义的行为。对象实际上不会移动该对象。但需要注意,这样做会违反。

2024-05-18 10:05:48 648

原创 关于os进程

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

2024-03-09 16:57:11 416

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

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

2024-03-09 15:55:44 491

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

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

2024-02-26 20:06:29 736

原创 netfilter内核实现

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

2024-02-26 20:01:04 480

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

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

2024-02-26 19:56:26 414

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

unordered_map需要用pair初始化。

2024-02-24 16:01:57 340

转载 蓝牙协议入门

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

2024-02-08 11:20:33 80

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

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

2024-02-08 10:16:51 524 2

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

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

2024-02-08 10:12:41 416

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

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

2024-02-07 16:29:20 474

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

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

2024-02-07 14:36:21 444

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

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

2024-01-18 16:37:42 557

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

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

2024-01-18 11:35:53 2029

原创 redis为什么快

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

2024-01-18 11:32:31 795

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

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

2024-01-18 11:17:32 1391

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

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

2024-01-12 01:15:01 640

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

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

2024-01-11 10:37:06 386

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

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

2024-01-11 10:31:12 411

原创 vector map迭代器失效问题

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

2024-01-10 11:15:28 554

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

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

2024-01-08 21:15:36 545

转载 关于TIME_WAIT

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

2024-01-08 20:17:57 62

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

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

2024-01-08 19:50:57 602

原创 2pc和3pc的区别

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

2024-01-08 15:47:21 390

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

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

2024-01-08 09:08:19 532

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

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

2024-01-04 09:14:22 595

原创 Proactor和Reactor区别

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

2023-12-27 16:43:45 513

空空如也

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

TA关注的人

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