C++
文章平均质量分 90
总结一些C++的语法特性,概念。以及读书笔记、相关库
指针从不空
比特猫
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
glibc malloc 内存分配优化策略解读
内存分配器ptmalloc,即glibc中的malloc,实现了 malloc(),free()以及一组其它的函数,以提供动态内存管理的支持。分配器处在用户程序和内核之间,它响应用户的分配请求,向操作系统申请内存,然后将其返回给用户程序。为了保持高效的分配,分配器一般都会预先分配一块大于用户请求的内存,并通过算法管理这块内存。来满足用户的内存分配要求,用户释放掉的内存也并不是立即就返回给操作系统,相反,分配器会管理这些被释放掉的空闲空间,以应对用户以后的内存分配要求。原创 2024-07-20 20:00:00 · 1789 阅读 · 0 评论 -
TCP连接中的过程状态解析
TCP是一个面向连接的协议,所以在连接双方发送数据之前,都需要首先建立一条连接。当Client端调用socket函数调用时,相当于Client端产生了一个处于Closed状态的套接字。Client端又调用connect函数调用,系统为Client随机分配一个端口,连同传入connect中的参数(Server的IP和端口),这就形成了一个连接四元组,客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。原创 2024-07-28 20:00:00 · 1193 阅读 · 0 评论 -
探索 io_uring:理解高效异步 IO 的工作原理与实现细节
io_uring 是一个 Linux 内核提供的高性能异步 I/O 框架,最初在 Linux 5.1 版本中引入。它的设计目标是解决传统的异步 I/O 模型(如 epoll 或者 POSIX AIO)在大规模 I/O 操作中效率不高的问题。关键特点和优势包括:零拷贝操作:io_uring 允许应用程序直接将数据从用户空间提交给内核,而无需在用户空间和内核空间之间进行额外的数据拷贝操作,从而减少了系统调用的开销。原创 2024-07-20 20:30:42 · 1903 阅读 · 0 评论 -
Linux内核 mmap内存映射的实现原理
在研究Linux内核以及Linux系统编程的时候,经常会碰到mmap内存映射,mmap函数是实现高性能编程的一个关键点。原创 2024-07-28 20:00:00 · 1142 阅读 · 0 评论 -
深入理解 Linux Zero-copy 原理与实现策略图解
本文从I/O 缓冲区,用户态&内核态以及 I/O 模式等等知识点全面而又详尽地剖析了 Linux 系统的 I/O 底层原理,分析了 Linux 传统的 I/O 模式的弊端,进而引入 Linux Zero-copy 零拷贝技术的介绍和原理解析,通过将零拷贝技术和传统的 I/O 模式进行区分和对比,带领读者经历了 Linux I/O 的演化历史。原创 2024-07-21 20:10:58 · 1347 阅读 · 0 评论 -
Linux 进程间通信方式
管道:速度慢,容量有限,只有父子进程能通讯FIFO:任何进程间都能通讯,但速度慢消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题信号量:不能传递复杂消息,只能用来同步共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。原创 2024-08-03 20:00:00 · 955 阅读 · 0 评论 -
Linux epoll 机制——原理图解与源码实现分析
epoll的实现机制是通过内核与用户空间共享一个事件表,这个事件表中存放着所有需要监控的文件描述符以及它们的状态,当文件描述符的状态发生变化时,内核会将这个事件通知给用户空间,用户空间再根据事件类型进行相应的处理。原创 2024-07-21 19:00:00 · 2875 阅读 · 0 评论 -
深入理解CPU缓存一致性
速度快的存储硬件成本高、容量小,速度慢的成本低、容量大。为了权衡成本和速度,计算机存储分了很多层次,有寄存器、L1 cache、L2 cache、L3 cache、主存(内存)和硬盘等。根据程序的空间局部性和时间局部性原理,缓存命中率可以达到 70~90%。因此,增加缓存可以让整个存储系统的性能接近寄存器,并且每字节的成本都接近内存,所以缓存是存储体系结构的灵魂。原创 2024-05-25 18:05:36 · 1404 阅读 · 0 评论 -
spdlog日志库源码:日志记录器logger类
一个logger类对象代表一个日志记录器,为用户提供日志记录接口。每个 logger 对象都有一个唯一的名称,用于标识该 logger。logger 对象维护一个日志等级(如 DEBUG、INFO、WARN、ERROR 等)。只有当日志消息的等级高于或等于 logger 的当前等级时,消息才会被记录下来。logger 提供了多种接口方法,允许用户记录不同类型的日志消息(如字符串、格式化字符串、异常信息等)。其维护一个 sink 指针数组,指向日志的输出目标(如文件、控制台、远程服务器等)。原创 2024-05-30 17:42:12 · 1723 阅读 · 0 评论 -
解析C++ 网络输入输出缓冲区Buffer类的设计与实现(muduo库)
网络输入输出缓冲区(Buffer)是为了优化网络通信性能而设计的。通过将数据存储在缓冲区中,可以减少对网络的频繁访问,提高数据传输效率。缓冲区还可以帮助处理数据流中的突发性和短时延,使得数据的发送和接收更加稳定和可靠。原创 2024-05-15 17:37:35 · 1975 阅读 · 0 评论 -
spdlog日志库源码:输出通道sink
在 spdlog 日志库中,sinks 并不是一个单独的类,而是一系列类的集合,这些类以基类-派生类的形式组织,每一个 sink 派生类代表了一种输出日志消息的方式。输出目标可以是普通文件、标准输出 (stdout)、标准错误输出 (stderr)、系统日志 (syslog) 等等。其文件位于include/spdlog/sinks中。原创 2024-06-01 18:24:21 · 1639 阅读 · 0 评论 -
spdlog日志库源码:格式化类formatter
spdlog 中的 formatter 类用于定义日志消息的格式化规则。它负责将日志记录器接收到的日志消息按照预定义的格式转换成最终的输出字符串。这使得开发者可以灵活地控制日志的输出格式,包括时间戳、日志等级、消息内容等信息。相关概念Scope 指的是一个日志模式标记(pattern flag)对应的字段显示宽度范围。当使用固定宽度的 pattern flag(如 “%8X”、“%-8X”、“%=8!X”)时,该字段有一个特定的宽度,即 scope。如果 pattern flag 没有指定宽度,那么它被原创 2024-05-30 17:41:53 · 1488 阅读 · 0 评论 -
spdlog日志库源码:自定义异常类spdlog_ex
标准库异常类(std::exception)系列,能满足大多数使用异常的场景,但对系统调用异常及错误信息缺乏支持。spdlog通过继承std::exception,扩展对系统调用的支持,实现自定义异常类spdlog_ex。spdlog_ex类声明只是在std::exception基础上添加了string类型的msg_成员,提供支持errno的构造函数。原创 2024-05-29 15:37:27 · 909 阅读 · 0 评论 -
spdlog日志库源码:线程池thread_pool
thread_pool 使用了 mpmc_blocking_queue(多生产者-多消费者阻塞队列)来缓存日志消息。这个队列允许多个前端线程(生产者)同时向队列中添加日志消息,也允许多个后端线程(消费者)同时从队列中取出消息。前端线程是指用户调用日志记录功能的线程。当用户调用异步日志记录方法时,日志消息会被封装成 async_msg 对象,并放入 mpmc_blocking_queue 队列中。原创 2024-05-29 15:36:57 · 1339 阅读 · 0 评论 -
从源码解析Linux内核中的kfifo:C++实现单读单写无锁队列
kfifo是Linux内核的一个FIFO数据结构,采用环形循环队列的数据结构来实现,提供一个无边界的字节流服务,并且使用并行无锁编程技术,即单生产者单消费者场景下两个线程可以并发操作,不需要任何加锁行为就可以保证kfifo线程安全。原创 2024-05-15 17:38:10 · 821 阅读 · 0 评论 -
C++高效死锁检测——实现原理与应用(基于强连通分量)
在项目使用多进程、多线程过程中,因争夺资源而造成一种资源竞态,所以需加锁处理。如下图所示,线程 A 想获取线程 B 的锁,线程 B 想获取线程 C 的锁,线程 C 想获取线程 D 的锁, 线程 D 想获取线程 A 的锁,从而构建了一个资源获取环,当进程或者线程申请的锁处于相互交叉锁住的情况,就会出现死锁,它们将无法继续运行。死锁的存在是因为有资源获取环的存在,所以只要能检测出资源获取环,就等同于检测出死锁的存在。原创 2024-05-25 18:04:55 · 1433 阅读 · 0 评论 -
spdlog日志库源码:全局管理类registry
在用户具体使用spdlog时,通常通过一个注册中心(registry)类来实现。原创 2024-06-01 18:23:51 · 1281 阅读 · 0 评论 -
C++ 实现无锁队列——单读单写、多读多写
之前学习了 C++ 中原子变量的内存顺序,现在我们来看看原子变量和内存顺序的应用 – 无锁队列。本文介绍单写单读和多写多读的无锁队列的简单实现,从中可以看到无锁数据结构设计的一些基本思路。原创 2024-05-06 10:36:11 · 1996 阅读 · 0 评论 -
Linux Ubuntu 20.04 安装DPDK方法指南
Ubuntu 20.04安装DPDK,从安装依赖到运行dpdkhelloword。原创 2024-08-03 20:00:00 · 3014 阅读 · 2 评论 -
VS Code SSH 远程连接服务器及坑点解决
Linux服务器重装了一下,IP没有变化,结果VS Code再重连的时候就各种问题,导致把整个流程全部走了一遍,留个经验帖以备查看。原创 2024-06-23 16:53:11 · 11774 阅读 · 1 评论 -
解决nanobind库中C++与Python的多参数绑定不兼容
最近在写一个开源项目的扩展,用到了nanobind库来绑定多参数的C++模板,遇到了匪夷所思的问题。实质是abi不兼容。原创 2024-10-29 20:28:16 · 1030 阅读 · 0 评论 -
Linux Ubuntu 20.04 netmap安装
进入LINUX目录初始化环境需要长时间等待完成,出现以下界面不用担心(需要等半个小时到一个小时)等待到出现这步就成功了编译和安装会有一路这样的check 需要耐心等待。原创 2024-08-04 17:09:47 · 863 阅读 · 0 评论 -
Spdlog日志库的安装配置与源码解析(Linux)
为什么使用日志库而不是控制台输出?日志库通常提供了更丰富的功能,比如可以设置日志输出级别、输出到不同的目标(比如控制台、文件、网络等),以及格式化输出等。使用日志库可以使代码更易于维护。通过统一的日志接口,可以更容易地对日志输出进行修改、调整和管理,而不需要在代码的各个地方进行修改。使用日志库可以优化性能,比如通过缓冲输出、异步写入等方式来减少对程序性能的影响。而直接使用 cout 可能会导致频繁的 IO 操作,影响程序的性能。原创 2024-06-23 16:54:20 · 1810 阅读 · 0 评论 -
探究C++20协程(1)——C++协程概览
协程就是一段可以挂起(suspend)和恢复(resume)的程序,一般而言,就是一个支持挂起和恢复的函数。一般情况下,函数一旦开始,就无法暂停。如果一个函数能够暂停,那它就可以被认为是我们开头提到的协程。所以挂起(suspend)就可以理解成暂停,恢复(resume)就理解成从暂停的地方继续执行。Result 是按照协程的规则定义的类型,之后再详细介绍。在 C++ 20当中,一个函数的返回值类型如果是符合协程的规则的类型,那么这个函数就是一个协程。原创 2024-04-12 20:18:05 · 1701 阅读 · 0 评论 -
探究C++20协程(6)——实现协程之间消息传递
之前主要关注的是协程与外部调用者的交互,这次也关注一下对等的协程之间的通信。原创 2024-04-25 17:48:37 · 2055 阅读 · 0 评论 -
探究C++20协程(3)——通用异步任务Task的简单设计
其中,Result 的模板参数 T 对应于 Task 的返回值类型。有了这个结果类型就可以很方便地在需要读取结果的时候调用 get_or_throw。Promise type 是一个协程的基础结构,它定义了协程的返回类型、如何初始化和结束协程,以及协程在遇到 co_await、co_yield、和 co_return 时的行为。初始化和最终挂起:在协程开始执行前,会创建一个 promise 对象。当协程结束或最终挂起时,通过 promise 对象来清理和收尾。原创 2024-04-18 18:51:48 · 2119 阅读 · 0 评论 -
探究C++20协程(5)——基于挂起实现无阻塞的定时器
当用传统的线程 sleep 函数来让程序等待时,实际上是在阻塞当前线程。阻塞意味着这个线程在指定的时间(例如100毫秒)内无法执行任何其他任务。这种方式虽然简单,但效率低下,因为它导致CPU资源在等待期间未被充分利用。协程提供了一种更加高效的方式来处理这种等待情况。它们在单个线程内部执行,并且能够在不阻塞线程的情况下挂起和恢复。当一个协程遇到需要等待的操作(如 sleep)时,它会挂起自身,而不会阻塞所在的线程。这使得线程可以转而去执行其他的协程。这种挂起和恢复的过程是由协程调度器管理的。原创 2024-04-22 19:56:40 · 1642 阅读 · 0 评论 -
探究C++20协程(2)——取值、传值、销毁与序列生成器实现
序列生成器是一个非常经典的协程应用场景,尤其是在需要惰性生成数据或处理潜在无限的数据流时。序列生成器概念:序列生成器允许程序按需生成序列中的下一个元素,而不是一次性计算整个序列。这种方式可以节省内存,并允许处理无限或未知长度的数据序列。原创 2024-04-12 20:18:58 · 1617 阅读 · 0 评论 -
探究C++20协程(4)——协程中的调度器
协程本身并不能实现异步操作,它们需要依赖于调度器(Scheduler)的组件来实现异步操作。调度器负责管理协程的执行和调度。原创 2024-04-22 19:56:17 · 1815 阅读 · 3 评论 -
详解C++11原子变量、内存顺序及相关引用案例
C++11 将多线程纳入了标准。一旦涉及到多线程,就需要考虑并发,数据竞争 (date race),线程同步等问题。为此 C++ 提供了互斥锁 std::mutex,原子变量 std::atomic 等标准库。对于原子变量的操作,有一个很重要的概念就是内存顺序 (memory order),其中涉及到的概念很多,理解起来可能会有些困难。本文来从底层详解这个问题。其中 3.4 节和 3.5 节标注了星号,它们的实际应用较少,不感兴趣的可以先跳过,或者读完全文后再阅读。原创 2024-04-18 18:50:10 · 2269 阅读 · 0 评论 -
C++深入解析锁机制与 CAS 实现
CAS,是Compare and Swap的简称,在这个机制中有三个核心的参数: 主内存中存放的共享变量的值:V(一般情况下这个V是内存的地址值,通过这个地址可以获得内存中的值) 工作内存中共享变量的副本值,也叫预期值:A 需要将共享变量更新到的最新值:B原创 2024-05-06 10:35:05 · 2487 阅读 · 0 评论 -
揭示C++设计模式中的实现结构及应用——行为型设计模式
行为型模式(Behavioral Pattern)是对在不同的对象之间划分责任和算法的抽象化。行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。通过行为型模式,可以更加清晰地划分类与对象的职责,并研究系统在运行时实例对象 之间的交互。在系统运行时,对象并不是孤立的,它们可以通过相互通信与协作完成某些复杂功能,一个对象在运行时也将影响到其他对象的运行。原创 2024-04-27 21:56:06 · 960 阅读 · 0 评论 -
揭示C++设计模式中的实现结构及应用——结构型设计模式
结构型模式(Structural Pattern)描述如何将类或者对象结合在一起形成更大的结构,就像搭积木,可以通过 简单积木的组合形成复杂的、功能更为强大的结构。原创 2024-04-27 21:55:24 · 1036 阅读 · 0 评论 -
揭示C++设计模式中的实现结构及应用——创建型设计模式
创建型模式(Creational Pattern)对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。为了使软件的结构更加清晰,外界对于这些对象只需要知道它们共同的接口,而不清楚其具体的实现细节,使整个系统的设计更加符合单一职责原则。创建型模式在创建什么(What),由谁创建(Who),何时创建(When)等方面都为软件设计者提供了尽可能大的灵活性。创建型模式隐藏了类的实例的创建细节,通过隐藏对象如何被创建和组合在一起达到使整个系统独立的目的。原创 2024-04-25 17:54:52 · 968 阅读 · 0 评论 -
详解多态、虚继承、多重继承内存布局及虚表(C++)
详解C++多态、虚继承、多重继承内存布局,及虚函数表,虚表指针。原创 2024-04-07 18:25:33 · 2769 阅读 · 3 评论 -
C++11新特性之关键字
auto:让编译器在编译器就推导出变量的类型,可以通过=右边的类型推导出变量的类型。decltype:相对于auto用于推导变量类型,而decltype则用于推导表达式类型,这里只用于编译器分析表达式的类型,表达式实际不会进行运算。原创 2024-03-28 10:24:35 · 529 阅读 · 0 评论 -
C++11新特性之并发
c++11引入了std::thread来创建线程,支持对线程join或者detach。我们创建了一个线程t,然后调用join函数等待线程执行完毕。接着我们创建了另一个线程t2,然后调用detach函数来分离该线程。当线程被分离后,它会在后台继续执行,与主线程独立运行,主线程也可以继续执行其他工作。原创 2024-03-27 16:36:08 · 1859 阅读 · 0 评论 -
左右值引用,move语义,完美转发
讲解了左右值引用,move语义,移动构造函数,完美转发,返回优化原创 2023-01-08 18:50:14 · 1710 阅读 · 2 评论 -
C++中模板与泛型编程
函数模板语法:template<typename T>函数声明或定义template ,声明创建模板typename, 表面其后面的符号是—种数据类型,可以用class代替T ,通用的数据类型,名称可以替换,通常为大写字母template<typename T>void myswap(T& a, T& b) { T temp = a; a = b; b = temp;}函数模板注意事项:自动类型推导,必须推导出一致的数据类型T,才可原创 2021-04-12 17:11:48 · 402 阅读 · 0 评论 -
C++中虚析构函数和虚基类
虚函数原创 2021-04-04 22:17:24 · 565 阅读 · 0 评论
分享