Thread Learning
This commit is contained in:
190
Thread/Async-Future.md
Normal file
190
Thread/Async-Future.md
Normal 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全套用起来。
|
||||
|
||||
你想试吗?
|
||||
Reference in New Issue
Block a user