C++11 并发编程核心组件教程(初学者友好)

在 C++11 之前,C++ 标准库没有直接支持并发编程,开发者需要依赖操作系统 API(如 pthread、Windows 线程),代码移植性差且复杂。C++11 引入了 线程库(<thread>异步编程组件,让我们可以用标准语法编写跨平台的并发代码。

本教程将聚焦 7 个核心组件:futureshared_futureasynclaunchpromisepackaged_taskfuture_status,用「通俗解释 + 常用接口 + 带注释样例」的方式,帮你彻底理解并上手。

核心概念铺垫

在学具体组件前,先明确 2 个关键概念:

  • 异步操作:一个操作不会阻塞当前线程,而是在后台(其他线程)执行,当前线程可以继续做别的事。
  • 结果传递:异步操作的结果需要从「执行线程」传递到「等待线程」,C++11 用 future 系列组件实现这个“结果通道”。

简单说:你让别人帮你办事(异步操作),需要一个“取件凭证”(future),之后凭凭证拿结果——这就是这些组件的核心逻辑。

1. future:异步操作的“单例取件凭证”

通俗解释

future 是「未来的结果」的抽象,相当于你在快递柜寄件后拿到的 唯一取件码

  • 只能凭这个取件码取一次结果(取完后凭证失效);
  • 取结果时如果快递还没到(异步操作没完成),会阻塞当前线程,直到结果就绪;
  • 可以查询结果是否就绪,或设置等待超时。

头文件

#include <future>  // 所有异步组件都需要这个头文件

常用接口(核心 4 个)

接口 功能描述
get() 获取异步操作的结果(核心):
1. 未就绪时阻塞当前线程;
2. 只能调用一次(第二次调用行为未定义);
3. 若异步操作抛异常,get() 会重新抛出。
valid() 判断 future 是否有效(是否关联了一个异步操作):
- 刚创建的空 future 无效;
- get() 调用后失效。
wait() 阻塞当前线程,直到异步操作完成(只等结果,不拿结果)。
wait_for(duration) 超时等待:
- 若在 duration 时间内结果就绪,返回 future_status::ready
- 超时返回 future_status::timeout
- 异步操作被取消(如线程结束)返回 future_status::deferred(延迟执行)。

样例:用 future 获取异步任务结果

#include <iostream>
#include <future>
#include <chrono>  // 用于时间相关操作

// 模拟一个耗时任务:计算 a + b,延迟 2 秒
int add(int a, int b) {
    std::cout << "add 任务开始执行(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟耗时
    return a + b;
}

int main() {
    std::cout << "主线程开始(线程 ID:" << std::this_thread::get_id() << ")\n";

    // 1. 用 async 启动异步任务(后面会讲 async),返回 future<int> 作为取件凭证
    std::future<int> fut = std::async(add, 10, 20);  // add(10,20) 会在后台执行

    // 2. 主线程可以做其他事,不用等异步任务完成
    std::cout << "主线程正在做其他工作...\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));  // 模拟主线程工作

    // 3. 用 get() 拿结果:如果任务没完成,主线程会阻塞到任务完成
    std::cout << "等待异步任务结果...\n";
    int result = fut.get();  // 阻塞此处,直到 add 返回
    std::cout << "异步任务结果:10 + 20 = " << result << "\n";

    // 4. get() 后 future 失效,valid() 返回 false
    std::cout << "get() 后 future 是否有效?" << (fut.valid() ? "是" : "否") << "\n";

    return 0;
}

运行结果(线程 ID 不同是正常的)

主线程开始(线程 ID:140737353988864)
add 任务开始执行(线程 ID:140737353984768)
主线程正在做其他工作...
等待异步任务结果...
异步任务结果:10 + 20 = 30
get() 后 future 是否有效?否

关键注意

  • get() 是「消费型」的,只能调用一次!如果想多次获取结果,需要用 shared_future(后面讲)。
  • 空的 future(如 std::future<int> fut;valid() 返回 false,调用 get() 会崩溃。

2. shared_future:异步操作的“多例取件凭证”

通俗解释

shared_futurefuture 的“共享版”,相当于快递柜的 可复制取件码

  • 可以复制多个 shared_future 实例,都关联同一个异步操作;
  • 每个实例都能调用 get() 获取结果(多次调用也没问题);
  • 只要有一个实例调用 get() 并阻塞,其他实例调用 get() 会一起阻塞,直到结果就绪。

常用接口(和 future 基本一致)

接口 功能描述
get() 获取结果:可多次调用(不会失效),未就绪时阻塞。
valid() 判断是否关联异步操作(复制后的 shared_future 都有效)。
wait() / wait_for() future 功能一致,阻塞等待结果。

核心区别:future vs shared_future

特性 future shared_future
复制性 不可复制(只能移动,如 std::move 可复制(多个实例关联同一任务)
get() 调用次数 最多 1 次(调用后失效) 可多次调用(结果缓存,不会失效)
用途 单线程获取结果 多线程共享结果(如多个线程等待同一任务)

样例:多线程用 shared_future 获取同一结果

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

// 模拟耗时任务:返回当前时间戳(秒)
int64_t get_timestamp() {
    std::cout << "get_timestamp 任务开始执行(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟耗时
    return std::chrono::time_point_cast<std::chrono::seconds>(
        std::chrono::system_clock::now()
    ).time_since_epoch().count();
}

// 线程函数:用 shared_future 获取结果并打印
void print_result(std::shared_future<int64_t> sfut, const std::string& thread_name) {
    std::cout << thread_name << " 开始等待结果(线程 ID:" << std::this_thread::get_id() << ")\n";
    int64_t ts = sfut.get();  // 可多次调用,结果相同
    std::cout << thread_name << " 获取到结果:" << ts << "\n";
}

int main() {
    std::cout << "主线程开始(线程 ID:" << std::this_thread::get_id() << ")\n";

    // 1. 启动异步任务,得到 future
    std::future<int64_t> fut = std::async(get_timestamp);

    // 2. 转换为 shared_future(必须用 move,因为 future 不可复制)
    std::shared_future<int64_t> sfut = std::move(fut);

    // 3. 创建 3 个线程,共享同一个 shared_future
    std::thread t1(print_result, sfut, "线程1");
    std::thread t2(print_result, sfut, "线程2");
    std::thread t3(print_result, sfut, "线程3");

    // 4. 主线程也可以获取结果
    std::cout << "主线程等待结果...\n";
    int64_t main_ts = sfut.get();
    std::cout << "主线程获取到结果:" << main_ts << "\n";

    // 5. 等待子线程结束
    t1.join();
    t2.join();
    t3.join();

    return 0;
}

运行结果(顺序可能不同,但结果一致)

主线程开始(线程 ID:140737353988864)
get_timestamp 任务开始执行(线程 ID:140737353984768)
主线程等待结果...
线程1 开始等待结果(线程 ID:140737353980672)
线程2 开始等待结果(线程 ID:140737353976576)
线程3 开始等待结果(线程 ID:140737353972480)
主线程获取到结果:1730700000
线程1 获取到结果:1730700000
线程2 获取到结果:1730700000
线程3 获取到结果:1730700000

关键注意

  • 必须通过 std::move(fut)future 转换为 shared_future,因为 future 不支持复制构造/赋值。
  • shared_futureget() 是「非消费型」的,多次调用返回同一个结果,适合多线程共享。

3. async:异步任务的“快捷启动器”

通俗解释

std::async 是 C++11 提供的 最简单的异步任务启动函数,相当于“一键下单”:

  • 自动创建线程(或复用线程)执行任务;
  • 自动返回一个 future(取件凭证),无需手动管理线程和结果传递;
  • 支持两种执行策略(通过 launch 参数控制)。

函数原型(核心)

template <class F, class... Args>
std::future<typename std::result_of<F(Args...)>::type>
async(std::launch policy, F&& f, Args&&... args);
  • policy:执行策略(可选,默认是 launch::async | launch::deferred);
  • f:要执行的任务(函数、函数对象、lambda 等);
  • args:任务的参数;
  • 返回值:future<T>T 是任务 f 的返回值类型。

常用接口(就是函数本身,重点在执行策略)

执行策略(launch 枚举)

std::launch 是枚举类型,控制 async 的执行方式,有 3 种常用组合:

策略 功能描述
launch::async 强制创建新线程,异步执行任务(任务会立即启动)。
launch::deferred 延迟执行:任务不会启动,直到调用 future::get()wait() 时,才在当前线程同步执行。
`launch::async launch::deferred`(默认)

样例 1:默认策略(自动选择)

#include <iostream>
#include <future>
#include <chrono>

void task(const std::string& name) {
    std::cout << name << " 执行中(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main() {
    std::cout << "主线程 ID:" << std::this_thread::get_id() << "\n";

    // 默认策略:async | deferred
    std::future<void> fut = std::async(task, "默认策略任务");

    std::cout << "主线程等待 0.5 秒...\n";
    std::this_thread::sleep_for(std::chrono::milliseconds(500));

    std::cout << "调用 get() 等待任务完成...\n";
    fut.get();  // 若任务是 deferred,会在此处同步执行(线程 ID 和主线程相同)

    return 0;
}

样例 2:强制异步(launch::async)

// 仅修改 async 的策略参数,其他代码和样例 1 一致
std::future<void> fut = std::async(std::launch::async, task, "强制异步任务");
运行结果(任务线程 ID 与主线程不同)
主线程 ID:140737353988864
主线程等待 0.5 秒...
强制异步任务 执行中(线程 ID:140737353984768)
调用 get() 等待任务完成...

样例 3:延迟执行(launch::deferred)

// 仅修改策略参数
std::future<void> fut = std::async(std::launch::deferred, task, "延迟执行任务");
运行结果(任务线程 ID 与主线程相同,因为在 get() 时同步执行)
主线程 ID:140737353988864
主线程等待 0.5 秒...
调用 get() 等待任务完成...
延迟执行任务 执行中(线程 ID:140737353988864)

关键注意

  • async 是「高层封装」,无需手动管理 std::threadjoin()detach(),避免线程泄漏;
  • 默认策略可能导致“延迟执行”,如果需要确保异步(新线程),必须显式指定 launch::async
  • 任务的参数会被复制/移动到异步线程,若要传递引用,需用 std::ref()std::cref()(如 std::async(task, std::ref(x)))。

4. launch:async 的“执行策略开关”

通俗解释

std::launch 是枚举类型,专门用来控制 std::async 的执行方式,相当于“开关”:

  • 开「异步模式」(launch::async):立刻开新线程执行;
  • 开「延迟模式」(launch::deferred):按需同步执行;
  • 开「自动模式」(默认):系统帮你选。

完整枚举定义(C++11 标准)

enum class launch {
    async = 1,        // 异步执行
    deferred = 2,     // 延迟执行
    // 以下是扩展(部分编译器支持)
    any = async | deferred  // 等价于默认值
};

样例:对比三种策略的执行时机

#include <iostream>
#include <future>
#include <chrono>

void test_task(const std::string& policy_name) {
    std::cout << "[" << policy_name << "] 任务启动(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main() {
    std::cout << "主线程 ID:" << std::this_thread::get_id() << "\n";
    std::cout << "-------------------------\n";

    // 1. launch::async:立即启动新线程
    auto fut1 = std::async(std::launch::async, test_task, "async");
    std::this_thread::sleep_for(std::chrono::milliseconds(200));  // 等 0.2 秒,观察任务是否启动
    std::cout << "[" << "async" << "] 调用 get()\n";
    fut1.get();

    std::cout << "-------------------------\n";

    // 2. launch::deferred:调用 get() 时才启动(同步执行)
    auto fut2 = std::async(std::launch::deferred, test_task, "deferred");
    std::this_thread::sleep_for(std::chrono::milliseconds(200));  // 等 0.2 秒,任务不会启动
    std::cout << "[" << "deferred" << "] 调用 get()(此时任务才启动)\n";
    fut2.get();

    std::cout << "-------------------------\n";

    // 3. 默认策略(async | deferred):系统自动选择
    auto fut3 = std::async(test_task, "default");
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    std::cout << "[" << "default" << "] 调用 get()\n";
    fut3.get();

    return 0;
}

运行结果(重点看任务启动时机)

主线程 ID:140737353988864
-------------------------
[async] 任务启动(线程 ID:140737353984768)
[async] 调用 get()
-------------------------
[deferred] 调用 get()(此时任务才启动)
[deferred] 任务启动(线程 ID:140737353988864)
-------------------------
[default] 任务启动(线程 ID:140737353984768)  // 不同编译器可能是 deferred,取决于系统
[default] 调用 get()

关键注意

  • launch::async 保证创建新线程,但可能因系统资源不足失败(抛出 std::system_error);
  • launch::deferred 不会创建新线程,适合轻量任务,避免线程创建开销;
  • 默认策略的行为是「未指定」的,不同编译器(如 GCC、Clang、MSVC)可能有不同实现,不要依赖默认策略的执行方式。

5. promise:手动设置异步结果的“承诺”

通俗解释

promise 是「承诺」:一个线程(生产者)向另一个线程(消费者)承诺“我会给你一个结果”,并通过 promise 主动设置结果,消费者用 future 取结果。

相当于:你让朋友帮你带奶茶,朋友说“好,我买到了告诉你”(承诺),朋友买到后会主动通知你(设置结果),你等着就行(用 future 等)。

核心逻辑

  1. 主线程创建 promise<T> 对象(T 是结果类型);
  2. promise::get_future() 获取关联的 future<T>,传递给消费者线程;
  3. 生产者线程执行任务,用 promise::set_value() 设置结果(或 set_exception() 设置异常);
  4. 消费者线程用 future::get() 获取结果(未设置时阻塞)。

常用接口

接口 功能描述
get_future() 返回关联的 future<T>(一个 promise 只能调用一次,多次调用行为未定义)。
set_value(const T& val) 设置结果 val
- 只能调用一次(多次调用崩溃);
- 调用后 future 就绪,get() 可获取结果。
set_exception(ex) 设置异常(如 std::make_exception_ptr(std::runtime_error("错误"))):
- 消费者调用 get() 时会重新抛出该异常。
~promise() 析构函数:若未设置结果/异常,会设置一个「broken promise」异常,消费者 get() 时抛出。

样例 1:正常设置结果

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

// 生产者线程:计算结果并设置到 promise
void producer(std::promise<int> prom) {  // 注意:promise 不可复制,需按值传递(或用 std::move)
    std::cout << "生产者线程开始(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟耗时计算
    int result = 100 * 200;  // 计算结果
    prom.set_value(result);  // 设置结果,promise 失效
    std::cout << "生产者线程设置结果完成\n";
}

int main() {
    std::cout << "主线程开始(线程 ID:" << std::this_thread::get_id() << ")\n";

    // 1. 创建 promise 对象
    std::promise<int> my_prom;

    // 2. 获取关联的 future(取件凭证)
    std::future<int> fut = my_prom.get_future();

    // 3. 启动生产者线程,传递 promise(必须 move,因为不可复制)
    std::thread prod_thread(producer, std::move(my_prom));

    // 4. 主线程(消费者)等待结果
    std::cout << "主线程等待生产者结果...\n";
    int result = fut.get();  // 阻塞,直到生产者 set_value
    std::cout << "主线程获取到结果:" << result << "\n";

    // 5. 等待生产者线程结束
    prod_thread.join();

    return 0;
}

运行结果

主线程开始(线程 ID:140737353988864)
主线程等待生产者结果...
生产者线程开始(线程 ID:140737353984768)
生产者线程设置结果完成
主线程获取到结果:20000

样例 2:设置异常(错误处理)

#include <iostream>
#include <future>
#include <thread>
#include <chrono>
#include <stdexcept>

// 生产者线程:模拟执行失败,设置异常
void producer_with_error(std::promise<int> prom) {
    std::cout << "生产者线程开始(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));

    try {
        // 模拟执行错误
        throw std::runtime_error("计算时发生除零错误!");
    } catch (...) {
        // 捕获异常,设置到 promise
        prom.set_exception(std::current_exception());  // 传递当前异常
    }
}

int main() {
    std::promise<int> my_prom;
    std::future<int> fut = my_prom.get_future();
    std::thread prod_thread(producer_with_error, std::move(my_prom));

    std::cout << "主线程等待结果...\n";
    try {
        int result = fut.get();  // 会重新抛出生产者设置的异常
        std::cout << "结果:" << result << "\n";
    } catch (const std::exception& e) {
        std::cout << "主线程捕获到异常:" << e.what() << "\n";
    }

    prod_thread.join();
    return 0;
}

运行结果

主线程等待结果...
生产者线程开始(线程 ID:140737353984768)
主线程捕获到异常:计算时发生除零错误!

关键注意

  • promise 不可复制,只能移动(如 std::move(my_prom));
  • 必须调用 set_value()set_exception(),否则 promise 析构时会设置「broken promise」异常,导致消费者 get() 崩溃;
  • get_future() 只能调用一次,多次调用会抛出异常。

6. packaged_task:包装可调用对象的“任务包装器”

通俗解释

packaged_task 是「任务包装器」:将一个可调用对象(函数、lambda、函数对象)包装成一个“带结果通道的任务”,包装后可以:

  • 像普通函数一样调用(执行任务);
  • 通过 get_future() 获取 future,用于获取任务执行结果。

相当于:你把“做蛋糕”的步骤(函数)包装成一个“蛋糕任务包”,任务包自带“取蛋糕的凭证”(future),执行任务包(做蛋糕)后,凭凭证拿蛋糕(结果)。

核心逻辑

  1. packaged_task<T(Args...)> 包装任务(T 是返回值类型,Args 是参数类型);
  2. get_future() 获取关联的 future
  3. 执行包装的任务(直接调用 packaged_task 对象,或传递给线程执行);
  4. future::get() 获取结果。

常用接口

接口 功能描述
packaged_task(F&& f) 构造函数:包装可调用对象 f(函数、lambda 等)。
get_future() 返回关联的 future<T>(一个 packaged_task 只能调用一次)。
operator()(Args&&… args) 执行包装的任务:
- 传入参数 args,调用包装的函数;
- 执行完成后,future 就绪。
valid() 判断是否包装了有效的任务(未移动、未析构)。
reset() 重置 packaged_task,允许重新获取 future 并执行(部分编译器支持)。

样例 1:直接调用 packaged_task

#include <iostream>
#include <future>
#include <chrono>

// 普通函数:计算阶乘
int factorial(int n) {
    std::cout << "计算 " << n << "! 开始...\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
    int result = 1;
    for (int i = 1; i <= n; ++i) {
        result *= i;
    }
    return result;
}

int main() {
    std::cout << "主线程开始\n";

    // 1. 包装任务:packaged_task<int(int)> 表示“输入 int,返回 int”的任务
    std::packaged_task<int(int)> task(factorial);

    // 2. 获取 future
    std::future<int> fut = task.get_future();

    // 3. 执行包装的任务(直接调用,在主线程执行)
    task(5);  // 等价于 factorial(5)

    // 4. 获取结果
    int result = fut.get();
    std::cout << "5! = " << result << "\n";

    return 0;
}

运行结果

主线程开始
计算 5! 开始...
5! = 120

样例 2:传递给线程执行(异步执行任务)

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

// lambda 表达式作为任务(计算两数之和)
auto add_task = [](int a, int b) {
    std::cout << "add_task 执行(线程 ID:" << std::this_thread::get_id() << ")\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return a + b;
};

int main() {
    std::cout << "主线程开始(线程 ID:" << std::this_thread::get_id() << ")\n";

    // 1. 包装 lambda 任务:输入两个 int,返回 int
    std::packaged_task<int(int, int)> task(add_task);

    // 2. 获取 future
    std::future<int> fut = task.get_future();

    // 3. 传递给线程执行(必须 move,因为 packaged_task 不可复制)
    std::thread t(std::move(task), 30, 40);  // 任务参数:30 和 40

    // 4. 主线程做其他事
    std::cout << "主线程等待结果...\n";

    // 5. 获取结果
    int result = fut.get();
    std::cout << "30 + 40 = " << result << "\n";

    t.join();
    return 0;
}

运行结果

主线程开始(线程 ID:140737353988864)
主线程等待结果...
add_task 执行(线程 ID:140737353984768)
30 + 40 = 70

关键注意

  • packaged_task 不可复制,只能移动(传递给线程时必须用 std::move);
  • 必须执行 operator()(调用任务),否则 future::get() 会一直阻塞(直到线程结束,promise 析构抛出异常);
  • 适合需要“先包装任务,后执行”的场景(如任务队列),比 async 更灵活(可手动控制任务执行时机)。

7. future_status:future 等待的“状态返回值”

通俗解释

future_status 是枚举类型,用于 future::wait_for()future::wait_until() 的返回值,告诉你“等待的结果怎么样了”:

  • 结果准备好了(ready);
  • 等待超时了(timeout);
  • 任务是延迟执行的(deferred,还没开始)。

相当于:你等快递,快递员告诉你三种情况:“快递到了”“超时没到”“快递还没发货(延迟了)”。

枚举定义

enum class future_status {
    ready,    // 结果已就绪
    timeout,  // 等待超时
    deferred  // 任务是延迟执行的(未启动)
};

常用场景

  • 非阻塞获取结果:避免 get() 一直阻塞,定期检查结果是否就绪;
  • 超时处理:等待一段时间后如果结果还没到,做其他处理(如重试、放弃)。

样例:用 wait_for() 和 future_status 实现超时等待

#include <iostream>
#include <future>
#include <chrono>

// 耗时任务:延迟 3 秒返回结果
int long_task() {
    std::cout << "长任务开始执行(需要 3 秒)...\n";
    std::this_thread::sleep_for(std::chrono::seconds(3));
    return 999;
}

int main() {
    std::cout << "主线程开始\n";

    // 启动异步任务(强制异步)
    std::future<int> fut = std::async(std::launch::async, long_task);

    // 循环等待,每次等待 1 秒,检查状态
    while (true) {
        // wait_for(1s):等待 1 秒,返回 future_status
        std::future_status status = fut.wait_for(std::chrono::seconds(1));

        if (status == std::future_status::ready) {
            // 结果就绪,获取结果
            std::cout << "任务完成!结果:" << fut.get() << "\n";
            break;
        } else if (status == std::future_status::timeout) {
            // 超时,继续等待
            std::cout << "等待超时(已等 1 秒),继续等待...\n";
        } else if (status == std::future_status::deferred) {
            // 任务延迟执行,调用 get() 同步执行
            std::cout << "任务是延迟执行的,现在同步执行...\n";
            std::cout << "结果:" << fut.get() << "\n";
            break;
        }
    }

    return 0;
}

运行结果

主线程开始
长任务开始执行(需要 3 秒)...
等待超时(已等 1 秒),继续等待...
等待超时(已等 1 秒),继续等待...
任务完成!结果:999

样例 2:处理延迟执行的任务

#include <iostream>
#include <future>
#include <chrono>

void deferred_task() {
    std::cout << "延迟任务执行中...\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main() {
    // 延迟执行策略
    std::future<void> fut = std::async(std::launch::deferred, deferred_task);

    std::future_status status = fut.wait_for(std::chrono::seconds(1));
    if (status == std::future_status::deferred) {
        std::cout << "检测到延迟任务,调用 get() 同步执行...\n";
        fut.get();  // 此时任务才执行
    }

    return 0;
}

运行结果

检测到延迟任务,调用 get() 同步执行...
延迟任务执行中...

关键注意

  • wait_for() 的超时时间是“至少”等待这么久,实际等待时间可能略长(取决于系统调度);
  • 只有当任务是 launch::deferred 时,才会返回 future_status::deferred
  • 适合需要“非阻塞等待”或“超时控制”的场景,比单纯的 get() 更灵活。

总结:7 个组件的核心用途

组件 核心用途 一句话记忆
future 单线程获取异步结果(唯一凭证) 唯一取件码
shared_future 多线程共享异步结果(可复制凭证) 可复制取件码
async 快捷启动异步任务(自动管理线程和 future) 一键下单(异步任务)
launch 控制 async 的执行策略(异步/延迟) 异步任务的开关
promise 手动设置异步结果/异常(生产者→消费者) 结果承诺(主动设置)
packaged_task 包装可调用对象,生成带 future 的任务 任务包装器(自带取件凭证)
future_status 表示 wait_for() 的等待状态(就绪/超时/延迟) 等待结果的状态报告

学习建议

  1. 先掌握 async + future:最简单的异步编程组合,覆盖 80% 的基础场景;
  2. 再学 promise + future:理解手动传递结果的逻辑,适合复杂线程通信;
  3. 然后学 packaged_task:灵活包装任务,适合任务队列等场景;
  4. 最后学 shared_futurefuture_status:处理多线程共享和超时控制。

多写代码练习(比如用这些组件实现“线程池”“异步下载”等小功能),就能熟练掌握啦!如果有疑问,欢迎随时交流~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐