Thread Learning

This commit is contained in:
e2hang
2025-12-31 12:49:32 +08:00
parent a047893756
commit 09dd277cee
4 changed files with 1092 additions and 0 deletions

190
Thread/Async-Future.md Normal file
View File

@@ -0,0 +1,190 @@
哈哈,好的,你现在已经把 **线程、互斥、原子**都啃完了,剩下的就是 **“有返回值的并发”**——也就是 `<future>` / `<async>` 的领域了。
我给你整理一份 **速查表+说明**,保证看完就能用。
---
# 一、`std::async` 基本概念
> **作用**:开启一个任务,并且自动管理线程,可以**拿返回值**。
> 它本质是“带未来值的线程”。
### 1⃣ 基本用法
```cpp
#include <future>
#include <iostream>
using namespace std;
int work(int x) { return x * x; }
int main() {
future<int> f = async(work, 5);
int result = f.get(); // 阻塞直到返回值就绪
cout << result << endl; // 25
}
```
### 参数详解
```cpp
async(launch::policy policy, Callable f, Args... args)
```
* `policy` 可选:
* `launch::async` → 必在新线程运行
* `launch::deferred` → 等到调用 `get()` 才执行(懒加载)
* 可以用 `|` 混合
* `f` → 函数或 lambda
* `args...` → 参数
### 返回值
* `std::future<R>`
* `get()` 得到实际返回值
* 阻塞直到任务完成
* 调用一次 `get()` 后 future 失效
---
# 二、`std::future` 基本操作
| 函数 | 作用 | 返回值 |
| ------------------------ | -------- | --------------- |
| `get()` | 阻塞等待结果 | `R` |
| `wait()` | 阻塞直到准备好 | void |
| `wait_for(duration)` | 阻塞指定时间 | `future_status` |
| `wait_until(time_point)` | 阻塞到指定时间点 | `future_status` |
| `valid()` | 是否有有效任务 | bool |
`future_status` 枚举:
```cpp
std::future_status::ready // 已就绪
std::future_status::timeout // 超时
std::future_status::deferred // 延迟执行
```
---
# 三、`std::promise`future 的搭档)
> **作用**:手动给 future 设置值
```cpp
#include <future>
std::promise<int> p;
std::future<int> f = p.get_future();
// 子线程
std::thread([&p](){
p.set_value(42);
}).detach();
// 主线程
int val = f.get(); // 42
```
### 关键点
* `set_value()` → 给 future 赋值
* `set_exception()` → 把异常传给 future
* `get_future()` → 得到与 promise 绑定的 future
---
# 四、组合 async + future + lambda最常用
```cpp
auto f = async([](int x){ return x*2; }, 10);
cout << f.get(); // 20
```
* 不用手动管理线程
* 可以拿返回值
* 自动 join / 管理
---
# 五、等待与超时(高级)
```cpp
future<int> f = async(work, 5);
if(f.wait_for(500ms) == future_status::ready) {
cout << f.get() << endl;
} else {
cout << "还没完成" << endl;
}
```
* 非阻塞方式获取结果
* 用于并行计算 + 超时控制
---
# 六、`future` 全家桶速查表
| 类型 / 函数 | 作用 | 返回值 |
| ------------------------ | ------------- | ------------- |
| `std::future<T>` | 保存异步任务结果 | — |
| `get()` | 阻塞获取结果 | `T` |
| `wait()` | 阻塞直到就绪 | void |
| `wait_for(duration)` | 阻塞指定时间 | future_status |
| `wait_until(time_point)` | 阻塞到指定时间点 | future_status |
| `valid()` | 是否有效 | bool |
| `std::promise<T>` | 手动设置 future 值 | — |
| `set_value()` | 设置值 | void |
| `set_exception()` | 设置异常 | void |
| `get_future()` | 获取 future | future<T> |
| `std::async()` | 开启任务 | future<T> |
---
# 七、使用建议
1**如果需要返回值 → 用 async 或 promise/future**
2**不用 async 就直接 thread + mutex/atomic → 仅做“干活”**
3**async + lambda 最简洁**,避免手动 join / detach
4**多线程大计算 → future + async + wait_for**,保证不会死锁
---
# 八、示例:多线程计算 + 获取返回值
```cpp
#include <future>
#include <vector>
#include <iostream>
using namespace std;
int work(int x){ return x*x; }
int main(){
vector<future<int>> tasks;
for(int i=1; i<=4; i++){
tasks.push_back(async(work, i));
}
for(auto &f: tasks){
cout << f.get() << " ";
}
cout << endl;
}
```
输出:`1 4 9 16`(顺序可能一样也可能不同)
---
总结一句话:
> **thread → 干活**
> **mutex/atomic → 防抢/快抢**
> **future/async → 干活 + 拿结果**
> **promise → 未来值的手动操控**
---
我可以帮你 **把之前的“拷贝大文件”项目升级成 async + future 版本**,实现 **多线程拷贝 + 返回每个块的字节数 + 进度统计**,让你真正把线程+future全套用起来。
你想试吗?