4.8 KiB
4.8 KiB
哈哈,好的,你现在已经把 线程、互斥、原子都啃完了,剩下的就是 “有返回值的并发”——也就是 <future> / <async> 的领域了。
我给你整理一份 速查表+说明,保证看完就能用。
一、std::async 基本概念
作用:开启一个任务,并且自动管理线程,可以拿返回值。 它本质是“带未来值的线程”。
1️⃣ 基本用法
#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
}
参数详解
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 枚举:
std::future_status::ready // 已就绪
std::future_status::timeout // 超时
std::future_status::deferred // 延迟执行
三、std::promise(future 的搭档)
作用:手动给 future 设置值
#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()→ 把异常传给 futureget_future()→ 得到与 promise 绑定的 future
四、组合 async + future + lambda(最常用)
auto f = async([](int x){ return x*2; }, 10);
cout << f.get(); // 20
- 不用手动管理线程
- 可以拿返回值
- 自动 join / 管理
五、等待与超时(高级)
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 |
std::async() |
开启任务 | future |
七、使用建议
1️⃣ 如果需要返回值 → 用 async 或 promise/future 2️⃣ 不用 async 就直接 thread + mutex/atomic → 仅做“干活” 3️⃣ async + lambda 最简洁,避免手动 join / detach 4️⃣ 多线程大计算 → future + async + wait_for,保证不会死锁
八、示例:多线程计算 + 获取返回值
#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全套用起来。
你想试吗?