Files
CWithClasses/Thread/Async-Future.md
2025-12-31 12:49:32 +08:00

191 lines
4.8 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

哈哈,好的,你现在已经把 **线程、互斥、原子**都啃完了,剩下的就是 **“有返回值的并发”**——也就是 `<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全套用起来。
你想试吗?