• 多进程并发和多线程并发

    并发是指在单个CPU核心上,通过快速切换任务,使得多个任务看起来像在同时进行。 并行是指在多个CPU核心上,多个任务真正在物理上同时进行。 这两种都是经典的并发服务器设计模式,它们的核心目标相同:同时处理多个客户端请求, 实现并发处理, 提高服务器的吞吐量和响应速度。 特性维度 多进程模型 (Fork) 多线程模型 (Pthread) ...
  • 内存分区

    程序的内存布局 (Process Memory Layout) 一个程序运行起来后,操作系统会为其分配一块虚拟内存空间。这块空间在逻辑上通常分为以下几个部分: 栈 (Stack): 用途:用于存储函数的局部变量(也叫临时变量)、函数参数、返回地址等。 特点:由编译器自动分配和释放。内存区域通常较小,且向下增长(即从高地址向低地址扩展)。每个线程都有自己独立的栈。 堆 ...
  • Volatile 和编译器优化

    编译器优化的核心目标是在不改变程序原始逻辑(即可观察行为)的前提下,对生成的机器码进行修改,以提升程序的运行效率或减小其体积。这些改进通常体现在两个方面: 执行速度:减少程序运行所需的总时钟周期。 代码体积:减小程序编译后生成的可执行文件的大小。 GCC 提供了一系列丰富的优化选项,让开发者可以根据具体需求在编译时间、调试便利性、运行速度和代码大小之间做出权衡。 具体操作是...
  • 三-五-零法则

    这个法则是关于如何正确管理类中的资源(尤其是动态分配的内存),避免内存泄漏和悬挂指针等问题的指导方针。它们是C++语言演化过程中逐步形成的三个阶段性法则。 法则一:三法则 (The Rule of Three) - C++98/03时代 核心思想:如果一个类需要程序员显式地定义析构函数、拷贝构造函数或拷贝赋值运算符 中的任意一个,那么它极有可能也需要定义所有这三个。 析构函数 ...
  • 概念

    变量相关 全局变量若在其他文件中使用,需要用extern关键字声明(告诉编译器该变量在其他文件中定义),否则会报错”未定义的引用”。 12// file1.cppint globalVar = 42; // 定义全局变量 12// file2.cppextern int globalVar; // 声明全局变量 若用”static”修饰的全局变量,仅限当前文件使用,避免与其他文件同名变...
  • 堆 (Heap) 堆也称作优先队列, 是一种特殊的树形数据结构,满足堆性质:在最大堆中,父节点的值总是大于等于其子节点的值;在最小堆中,父节点的值总是小于等于其子节点的值。 在 C++ 中,可以使用标准库中的 std::priority_queue 来实现堆, 需要头文件 <queue>。默认情况下,std::priority_queue 实现的是最大堆。如果需要实现...
  • 虚拟内存

    虚拟地址空间 虚拟内存 (Virtual Memory) 是现代操作系统中的一个重要概念。它通过将程序使用的地址空间虚拟化,使得每个进程都拥有一个独立的、连续的地址空间,从而实现了内存保护、内存共享和更高效的内存利用。 目前, 一个进程的虚拟地址空间通常被划分为以下几个部分: 1234567891011121314151617+-------------------+ (高地址)...
  • 6. 无锁并发数据结构设计

    无锁并发数据结构的定义 首先, 在探讨无锁和有锁之前, 我们先回顾一下阻塞 (Blocking) vs. 非阻塞 (Non-blocking) 阻塞 (Blocking) 数据结构/算法:这是我们前面章节(特别是第3、4、6章)主要讨论的方式。它们依赖于阻塞式的同步原语,如: - 互斥量 (std::mutex):调用 lock() 可能导致线程被挂起。 - 条件变量 (std:...
  • 2. 线程间共享数据

    共享数据带来的问题 并发编程为我们带来了更高的性能和响应能力,但也引入了新的挑战,尤其是在多个线程需要访问和修改共享数据时。正确地管理这些共享数据对于确保程序的正确性和稳定性至关重要。 条件竞争 (Race Condition) 这一节是理解并发编程为何困难的基石。它主要阐述了两个核心概念:不变量 (Invariants) 的破坏是问题的表现形式,而 数据竞争 (Data Race...
15678921