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

4.8 KiB
Raw Blame History

哈哈,好的,你现在已经把 线程、互斥、原子都啃完了,剩下的就是 “有返回值的并发”——也就是 <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::promisefuture 的搭档)

作用:手动给 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() → 把异常传给 future
  • get_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全套用起来。

你想试吗?