- 博客(193)
- 资源 (3)
- 问答 (1)
- 收藏
- 关注
原创 基于C++11CAS实现无锁队列
CAS操作——Compare & Set,或是 Compare & Swap,现在几乎所有的CPU指令都支持CAS的原子操作,X86下对应的是 CMPXCHG 汇编指令。有了这个原子操作,我们就可以用其来实现各种无锁(lock free)的数据结构。这个操作用C语言来描述就是下面这个样子:(代码来自词条)意思就是说,看一看内存*reg里的值是不是oldval,如果是的话,则对其赋值newval。我们可以看到,总是返回,于是,我们可以在操作之后对其进行测试,以查看它是否与oldval。
2025-05-17 15:13:55
766
原创 深入浅出之STL源码分析8_三个指针
在第一篇文章 深入浅出之STL源码分析1_vector基本操作-CSDN博客中有引出了下面的几个问题1.刚才我提到了我的编译器版本是g++ 11.4.0,而我们要讲解的是STL(标准模板库),那么二者之间的关系是什么?STL安装后我们到哪里去看源码?2.我们引入了头文件#include<vector>这里的vector的内容是什么?这中定义方式是干什么?<>的作用是什么?对于stl源码底层到底做了什么?把对应的数据插入到了哪个地址了?什么时候分配的虚拟内存?什么时候扩容?
2025-05-13 22:57:49
407
原创 深入浅出之STL源码分析3_#include<vector>里的内容
1.刚才我提到了我的编译器版本是g++ 11.4.0,而我们要讲解的是STL(标准模板库),那么二者之间的关系是什么?STL安装后我们到哪里去看源码?对于stl源码底层到底做了什么?把对应的数据插入到了哪个地址了?什么时候分配的虚拟内存?什么时候会分配物理内存?2.我们引入了头文件#include<vector>我们引入了头文件#include<vector>这里的vector的内容是什么?这里的vector的内容是什么?中有引出了下面的几个问题。
2025-05-11 17:11:55
120
原创 深入浅出之STL源码分析2_stl与标准库,编译器的关系
在第一篇博客中,从这个例子出发,我们将引出下面的几个问题1.刚才我提到了我的编译器版本是g++ 11.4.0,而我们要讲解的是STL(标准模板库),那么二者之间的关系是什么?STL安装后我们到哪里去看源码?2.我们引入了头文件#include<vector>这里的vector的内容是什么?这中定义方式是干什么?<>的作用是什么?对于stl源码底层到底做了什么?把对应的数据插入到了哪个地址了?什么时候分配的虚拟内存?什么时候扩容?什么时候会分配物理内存?下面我们来重点来说明下问题1.
2025-05-11 17:08:37
658
原创 深入浅出之STL源码分析7_模版实例化与全特化
5. 显示实例话和全特化的区别,之前我们在讨论类模版的时候,讨论过,他俩不是同一个概念,类模版中你如果全特化了,还是需要实例化才能生成代码,但是对于函数模版,这个是不同的,函数模版全特化后,就会生成代码。继续进行下验证,我们写一个函数模版的例子,看下全特化后的效果,再写一个类模版全特化的例子,看看再不实例化的情况下,结果是否相同,为了对比,我直接写在一起了。也就是函数模版特化和函数模版显示实例化可以达到相同的目的,那我现在就用全特化来达到相同的目的,继续修改function_template.cpp。
2025-05-11 16:16:15
314
原创 深入浅出之STL源码分析6_模版编译问题
如果不加以处理,这些相同的实体会被链接器认为是重定义的符号,这违反了ODR(One Definition Rule)。对这个问题的主流解决方案是为模板实例化生成的实体添加特殊标记,链接器在链接时对有标记的符号做特殊处理。例如在 GNU 体系下,模板实例化生成的符号都被标记为弱符号(Weak Symbol)。不需要我们参与,连接器已经为我们解决了这个问题。对于普通的函数和类,连接器是不会处理的。会报重定义的错误。同时这个因为每一个编译单元都有实例化,会带来代码膨胀。
2025-05-11 16:12:46
899
原创 深入浅出之STL源码分析5_类模版实例化与特化
其中隐式的实例化是我们平时最常用的实例化方式。隐式实例化,或者说按需实例化on-demand,是当我们要用这个模板生成实体的时候,要创建具体对象的时候,才做的实例化。显示实例化,也称为外部实例化,在不使用类模版的时候,将类模版实例化,显示实例化不是按需的,也就是不论是否调用对应的类成员函数,都会生成对应的成员函数。
2025-05-10 22:38:59
1309
原创 深入浅出之STL源码分析4_类模版
我们知道这里进行了类模板的声明。在类模版的内部,T1和T2可以像其他任何类型一样,用于声明成员变量和成员函数。这里要注意struct的成员默认是public的:用这个模版类型 _Alloc 直接或者间接的 定义了三个成员变量一个成员函数。我们先看这个pointer;
2025-05-10 21:52:59
1020
原创 C++11新特性:深入解析decltype关键字及其与auto的区别
C++11引入的和两大关键字彻底改变了类型推导的方式,但它们的核心目标和应用场景却大相径庭。理解它们的差异,是编写现代化、高可维护性C++代码的关键。本文将通过底层机制解析和实战案例对比,揭示它们的本质区别。
2025-05-10 11:09:17
294
原创 深入解析C++11 auto 关键字:类型推导的现代实践
不仅减少了代码冗余,还提高了代码的可维护性和灵活性。关键字彻底改变了开发者处理类型的方式。的工作原理、使用场景及最佳实践。值类型:忽略顶层const和引用。引用类型:保留底层const。
2025-05-10 10:52:56
169
原创 模版中的typename关键字详解
typename 关键字在 C++ 模板编程中有两个核心作用: 声明依赖类型名称:在模板中明确告诉编译器某个嵌套依赖名称是类型而非变量或函数。常见于访问模板参数内的嵌套类型(如 typename T::value_type)或类型特征库的类型提取(如 typename std::add_const<T>::type)。 模板类型参数声明:在模板参数列表中声明类型参数,与 class 关键字等价,但更推荐使用 typename 以提高代码清晰度。
2025-05-10 10:32:25
373
原创 深入解析C++11基于范围的for循环:更优雅的容器遍历方式
public:优势:代码简洁度提升50%+减少迭代器相关错误提高代码可维护性使用建议:优先使用const引用避免在循环体内修改容器结构复杂场景结合static_assert检查类型。
2025-05-02 08:59:21
323
原创 tbb parallel_for 使用教程2之 tbb::blocked_range
我们看下默认的颗粒度是1,这个颗粒度 grainsize 代表着给我们的任务分组,比方说我们上面的例子有10000个数,需要进行并行处理,则分成多少个组呢,那要看每个组里要多少个数据,一个组是在一个线程上执行,这个颗粒度 grainsize 就代表了每个组里最少有这么多的数据,注意是至少,一般tbb会在底层进行一个动态的负载均衡的。看下我们的输出,就是理论上每个分组里的数据大于等于1000.但是在实际的递归过程中可能小于1000,但是不会差太多,主要是递归的一个过程。
2025-04-30 15:29:22
462
原创 深入理解C++11 override关键字:编写更安全的虚函数重写
在传统C++开发中,虚函数重写时的签名错误常常导致隐蔽的运行时错误。彻底解决了这一痛点。
2025-04-30 09:01:46
725
原创 深入解析C++11 final关键字:如何限制继承与重写
在C++11标准中,final关键字的引入为面向对象编程带来了更精细的控制能力。它允许开发者显式声明禁止类被继承或禁止虚函数被子类重写,从而增强代码的稳定性和安全性。本文将深入探讨final的使用场景、技术细节以及它在现代C++开发中的实际价值。
2025-04-30 08:51:54
196
原创 C++ RAII 与RTTI 机制
在C++中,RAII(Resource Acquisition Is Initialization) 和 RTTI(Run-Time Type Information) 是两个核心机制,分别用于资源管理和运行时类型识别。
2025-04-23 09:01:39
253
原创 segment align 和page size
Linux x64 默认的页大小是 4KB,而不是 2M。在 Linux x64 中,可以使用`getconf` 命令查询虚拟内存页大小,如下所示:上述命令会输出当前 Linux 系统默认的虚拟内存页大小。在 x86_64 架构中,页表有 4 级,一个页表项的大小是 8 字节。因此,每个虚拟页面大小为 4KB,一个页表能够管理的虚拟地址大小是 512GB (2^48),整个虚拟地址空间大小是 128TB (2^48 * 2^9)。
2025-04-15 07:51:30
297
原创 readelf,objdump,nm,objcopy,ldd指令使用详解
本文主要讲解readelf,objdump,nm,objcopy,ldd指令的使用,以及实际的例子
2025-04-15 07:41:03
1168
原创 vector之内存分配详解
vector作为一种常见的容器,我们在日常的C++开发中,非常的常见,但是对于vector的使用过程中的内存分配情况,包括虚拟内存和物理内存的分配,感觉不是特别的清晰,作者也是想写一个demo,和大家一起来学习,在vector的使用过程中的内存分配情况。
2025-03-29 12:23:30
1089
原创 对RPC的简单理解
RPC全称为RemoteProcedureCall,即远过程调用。如果没有RPC,那么跨机器间的进程通讯通常得采用消息(网络通信tcp或者udp),这会降低开发效率,也会增加网络层和上层的耦合度,RPC可以帮助我们解决这些问题。其实就是他封装了这个网络通信的实现细节,与具体的通信不耦合,不用写网络通信的代码,自然就会提高开发效率。我在工作中用到的主要两种rpc就是Zeroc的ice,以及google的grpc....
2022-07-17 12:46:35
990
原创 Linux如何返回线程退出时的数据(以整数为例)
最近想写一篇std::future的文章,先来总结下,线程的退出值,以及如何回收这个退出值。这里主要参看了网上的文章,具体链接见文尾。在Linux中,线程的应用还是比较广泛的,同时,线程退出的返回值对线程来说,也是一种比较客观的数据传输。本文主要是在Linux中进行测试,不涉及windows等其他OS。1. 线程的创建 pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*start_routine)(..
2022-05-14 16:40:45
785
1
原创 C++线程池的实现
池式结构 在计算机体系结构中有许多池式结构:内存池、数据库连接池、请求池、消息队列、对象池等等。 池式结构解决的主要问题为缓冲问题,起到的是缓冲区的作⽤。 线程池通过使⽤线程池,我们可以有效降低多线程操作中任务申请和释放产⽣的性能消耗。特别是当我们每个线程的任务处理⽐较快时,系统 ⼤部分性能消耗都花在了pthread_create以及释放线程的过程中。那既然是这样的话,何不在程序开始运⾏阶段提前创建好⼀堆线程,等 我们需要⽤的时候只要去这⼀堆线程中领⼀个线程,⽤完了再放回去,等程.
2022-05-07 23:08:45
2787
原创 深入理解递归函数
1.递归函数概念介绍以及个人对递归的理解先给出一个概念:递归函数:我们把一个直接调用自己或通过一系列的调用语句间接地调用自己的函数,称做递归函数。一直都对递归有种敬畏之情,因为之前在一家公司里是不让写递归的,我记得当时的理由是递归代码比较晦涩,所以自己也就一直没有对递归深入的了解,但是随着时间的推移,我感觉有的时候,用递归写的代码是优雅的,递归应该算作是一种算法,或者编程技巧。当然递归也有自己的缺点,它会有函数间的不断调用,函数调用栈是比较消耗时间和内存的,同时如果递归结束条件写的不对,也会造成
2022-05-04 18:00:35
5798
原创 仿函数和重载<在sort和set中的应用
这里记录下仿函数和重载<在 sort和set 中的应用#include<iostream>#include<vector>#include<set>using namespace std;class Data{public: Data(int aa){ a_=aa; } /*bool operator < (const Data&d2) const{ return this-&.
2022-05-03 08:06:36
226
原创 Linux下静态库与动态库的引用关系深入分析
很久就想写一篇关于动态库和静态库互相引用的一篇文章,但是总感觉准备不充分,而一直没有勇气下笔,最近在和同事的讨论中,似乎有了一些新的认识,想把这些记录下来,和大家进行一次分享,同时也是做一次记录。这篇文章将从以下几个方面进行分析讲解1.程序的编译过程2.什么是静态编译,动态编译3.如何生成静态库,如何生成动态库4.动态库和静态库相互引用后,应用程序是否可以只使用一个库(例如:应用用到了静态库a,而静态库a里使用了库b,那么应用程序是不是只要链接a就可以了呢)5.动态库的两种加载方
2022-04-24 16:20:09
5678
原创 带继承和组合关系的类中构造函数和析构函数的调用顺序
1.构造函数构造函数的调用顺序如下:基类构造函数,C++提出的成员初始化列表,对象成员构造函数(非指针类型),派生类本身的构造函数。2.析构函数调用顺序,析构函数的调用顺序如下:(析构函数的调用顺序正好和构造函数的调用顺序相反)派生类本身的析构函数,对象成员的析构函数,基类的析构函数。这里没有写这个C++提出的成员初始化列表的原因是,他只是负责构造了,构造之后,析构就都是调用对象成员的析构函数了。这里给出具体的例子看下:首先这个例子先不给出 C++提出的成员初始化列表,让我们
2022-04-22 09:54:48
1407
2
原创 二叉树的深度优先遍历非递归深度解析
如上图二叉树的遍历主要思想就是通过递归方式进行遍历,同时如果要非递归遍历的话,一般情况下,深度优先遍历需要借助stack保存中间变量的方式进行遍历,广度优先遍历的话需要借助queue来保存每一层变量的方式进行遍历。对于深度优先遍历的递归的三种形式,不进行介绍,广度优先遍历,递归和非递归这篇文章也不进行介绍,这里就是想深刻的说下,深度优先遍历的三种非递归实现的原理。先说下三种遍历的实现顺序吧前序遍历:根,左,右中序遍历:左,根,右后续遍历:左,右,根因为二叉树给到我们的是根结点:...
2022-04-18 14:44:55
2425
LocationNavigate.dll
2019-09-24
当网络带宽满了以后数据发生丢失是在哪一层发生的?(ISO 5层模型)
2022-01-05
TA创建的收藏夹 TA关注的收藏夹
TA关注的人