C++11 并发编程核心组件教程(初学者友好)
C++11 并发编程核心组件教程(初学者友好)
在 C++11 之前,C++ 标准库没有直接支持并发编程,开发者需要依赖操作系统 API(如 pthread、Windows 线程),代码移植性差且复杂。C++11 引入了 线程库(<thread>) 和 异步编程组件,让我们可以用标准语法编写跨平台的并发代码。
本教程将聚焦 7 个核心组件:future、shared_future、async、launch、promise、packaged_task、future_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_future 是 future 的“共享版”,相当于快递柜的 可复制取件码:
- 可以复制多个
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_future的get()是「非消费型」的,多次调用返回同一个结果,适合多线程共享。
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::thread的join()或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 等)。
核心逻辑
- 主线程创建
promise<T>对象(T 是结果类型); - 用
promise::get_future()获取关联的future<T>,传递给消费者线程; - 生产者线程执行任务,用
promise::set_value()设置结果(或set_exception()设置异常); - 消费者线程用
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),执行任务包(做蛋糕)后,凭凭证拿蛋糕(结果)。
核心逻辑
- 用
packaged_task<T(Args...)>包装任务(T是返回值类型,Args是参数类型); - 用
get_future()获取关联的future; - 执行包装的任务(直接调用
packaged_task对象,或传递给线程执行); - 用
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() 的等待状态(就绪/超时/延迟) |
等待结果的状态报告 |
学习建议
- 先掌握
async + future:最简单的异步编程组合,覆盖 80% 的基础场景; - 再学
promise + future:理解手动传递结果的逻辑,适合复杂线程通信; - 然后学
packaged_task:灵活包装任务,适合任务队列等场景; - 最后学
shared_future和future_status:处理多线程共享和超时控制。
多写代码练习(比如用这些组件实现“线程池”“异步下载”等小功能),就能熟练掌握啦!如果有疑问,欢迎随时交流~
更多推荐



所有评论(0)