C with classes

This commit is contained in:
e2hang
2025-12-31 00:39:23 +08:00
commit a047893756
198 changed files with 11173 additions and 0 deletions

355
Thread/readme.md Normal file
View File

@@ -0,0 +1,355 @@
好,这个问题问得**非常到位**。
我直接给你一份 **「线程 / 并发编程全景图」**,从**你现在的水平**一路铺到**系统级 / 工程级**,不糊、不玄、不跳步。
你可以把这条线当成:
> **C / C++ 程序员从“会用线程”到“能写并发系统”的路线图**
---
# 一、线程到底是什么(地基)
### 1⃣ 线程 vs 进程(必须先立住)
| 对象 | 是否独立地址空间 | 开销 | 通信 |
| -- | ---------- | -- | ------ |
| 进程 | ✅ 有 | 大 | IPC |
| 线程 | ❌ 共享进程地址空间 | 小 | 直接共享内存 |
👉 **线程共享:**
* 全局变量
* 堆内存
* 文件描述符
👉 **线程私有:**
*
* 寄存器
* 程序计数器
⚠️ **线程 = 并发的根源 + BUG 的源头**
---
# 二、线程基础 API你已经碰到的部分
## 2⃣ 线程生命周期
以 C++ 为例:
```cpp
std::thread t(func);
t.join();
```
完整状态流转:
```
创建 → 就绪 → 运行 → 结束
被抢占
```
---
## 3⃣ join / detach线程管理
| 操作 | 作用 |
| ---------- | ---------- |
| `join()` | 等线程结束 |
| `detach()` | 后台运行,无法再控制 |
⚠️ **一个线程只能 join 一次**
---
# 三、线程最核心的问题:数据竞争 💥
## 4⃣ 什么是数据竞争Race Condition
```cpp
int x = 0;
void f() {
x++; // ❌ 非原子操作
}
```
两个线程同时执行:
```
load x
add 1
store x
```
👉 结果可能是:
* 1
* 2
* 乱七八糟UB
📌 **没有同步 = 行为未定义**
---
# 四、同步原语(并发的骨架)
## 5⃣ 互斥锁Mutex——第一大杀器
```cpp
std::mutex m;
void f() {
std::lock_guard<std::mutex> lock(m);
x++;
}
```
### Mutex 解决什么?
* 保证 **临界区** 同一时间只有一个线程进入
### 常见变种:
* `mutex`
* `recursive_mutex`
* `timed_mutex`
* `shared_mutex`(读多写少)
---
## 6⃣ 死锁(锁的黑暗面)☠️
```cpp
lock(A);
lock(B);
```
另一线程:
```cpp
lock(B);
lock(A);
```
💀 **两人对视,程序永恒**
### 解决方法:
* 统一加锁顺序
* `std::lock()`
* 层级锁lock hierarchy
---
## 7⃣ 条件变量Condition Variable
👉 **“我等一个条件成立”**
```cpp
std::condition_variable cv;
std::mutex m;
bool ready = false;
void worker() {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, []{ return ready; });
}
```
用途:
* 生产者-消费者
* 线程间通知
⚠️ **必须配合 mutex 使用**
---
# 五、原子操作(无锁并发)
## 8⃣ `std::atomic`(你迟早会用)
```cpp
std::atomic<int> x{0};
x++;
```
特点:
* 无锁(可能是 CPU 指令)
* 不会数据竞争
### 内存序(进阶但重要):
* `memory_order_relaxed`
* `acquire / release`
* `seq_cst`
👉 **这是并发里最难的一块**
---
# 六、线程模型 & 执行结构
## 9⃣ 线程池(工程级必备)
问题:
* 线程创建很贵
解决:
```text
任务队列 + 固定数量线程
```
用途:
* Web 服务器
* 游戏引擎
* 编译器
---
## 🔟 任务 vs 线程(现代并发思想)
| 概念 | 含义 |
| -- | ---- |
| 线程 | 执行单元 |
| 任务 | 要做的事 |
C++
* `std::async`
* `std::future`
* `std::promise`
---
# 七、系统层线程(你会很喜欢)
## 1⃣1⃣ OS 级线程实现
### Linux
* `pthread_create`
* `futex`
* 调度器CFS
### Windows
* `CreateThread`
* `WaitForSingleObject`
👉 **C++ `std::thread` 本质是封装**
---
## 1⃣2⃣ 用户态线程(协程)
| 类型 | 是否 OS 线程 |
| ----------- | -------- |
| std::thread | 是 |
| 协程 | 否 |
特点:
* 切换快
* 不能抢占
* 需要调度器
例子:
* C++20 coroutine
* Go goroutine
* libco / boost::coroutine
---
# 八、并发的“终极敌人”
## 1⃣3⃣ 可见性 & 内存模型
问题:
```cpp
flag = true; // 线程 A
while(!flag) {} // 线程 B
```
⚠️ **可能死循环**
原因:
* CPU cache
* 编译器重排
解决:
* atomic
* mutex
* memory barrier
---
## 1⃣4⃣ 假共享False Sharing
```cpp
struct {
int a;
int b;
};
```
a / b 在同一 cache line
两个线程写不同变量 → 性能暴死
---
# 九、你这个阶段最推荐的学习顺序 ✅
结合你**超偏底层 + 喜欢 C**的特点,我给你一个**实操导向路线**
### 第一阶段(立刻)
* `std::thread`
* `join / detach`
* `mutex`
* 数据竞争概念
### 第二阶段
* 生产者-消费者
* 条件变量
* 死锁分析
### 第三阶段(爽点)
* `std::atomic`
* lock-free 计数器
* 内存序
### 第四阶段(硬核)
* pthread + futex
* 调度器原理
* 协程实现
---
# 十、一句话总结(你现在的位置)
> **你已经站在“并发编程”的门口了**
> 接下来学的不是“语法”,而是:
> 👉 **CPU、内存、调度、同步的真实世界**
如果你愿意,下一步我可以直接带你:
* **手写一个线程池C / C++**
***用汇编 + C 看 atomic 指令**
***画一张“并发 BUG 地狱图”**
你选一个,我陪你打到懂为止 😈