异步不需要等待当前任务完成,就可以继续执行后续任务的处理方式。
async
std::async用于异步执行任务。它返回一个std::future对象,可以通过future.get()获取结果。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream> #include <future>
int add(int a, int b) { return a + b; }
int main() { std::future<int> result = std::async(add, 3, 4);
std::cout << result.get() << std::endl;
return 0; }
|
输出:
async 的启动策略
std::async 有两种常用启动策略:
1 2
| std::launch::async std::launch::deferred
|
std::launch::async
立即创建异步任务,通常会在新线程中执行。
1 2 3
| auto fut = std::async(std::launch::async, [] { return 100; });
|
std::launch::deferred
延迟执行任务。
只有当调用 get() 或 wait() 时,任务才会在当前线程执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> #include <future> #include <thread>
int main() { auto fut = std::async(std::launch::deferred, [] { std::cout << "执行线程 ID: " << std::this_thread::get_id() << std::endl; return 100; });
std::cout << "主线程 ID: " << std::this_thread::get_id() << std::endl;
std::cout << fut.get() << std::endl;
return 0; }
|
如果不指定策略:
实现可以自行选择是异步执行还是延迟执行。
如果希望一定异步执行,建议写:
1
| std::async(std::launch::async, func);
|
future
std::future表示一个未来可获得的结果。
常用方法:
1 2 3 4 5
| get(); wait(); wait_for(); wait_until(); valid();
|
get
获取异步任务结果。
注意:
get() 只能调用一次。
调用后 future 不再拥有结果。
wait
等待任务完成,但不获取结果。
wait_for
等待一段时间,检查任务是否完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <iostream> #include <future> #include <chrono> #include <thread>
int slowTask() { std::this_thread::sleep_for(std::chrono::seconds(2)); return 42; }
int main() { auto fut = std::async(std::launch::async, slowTask);
auto status = fut.wait_for(std::chrono::seconds(1));
if (status == std::future_status::ready) { std::cout << "结果: " << fut.get() << std::endl; } else { std::cout << "任务尚未完成" << std::endl; std::cout << "稍后结果: " << fut.get() << std::endl; }
return 0; }
|
promise
std::promise 用于在线程之间传递结果。
一个线程设置值,另一个线程通过 future 获取值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <iostream> #include <thread> #include <future>
void worker(std::promise<int> p) { int result = 10 + 20; p.set_value(result); }
int main() { std::promise<int> p; std::future<int> fut = p.get_future();
std::thread t(worker, std::move(p));
std::cout << "结果: " << fut.get() << std::endl;
t.join();
return 0; }
|
注意:
std::promise 不能复制,只能移动。
promise 传递异常
如果工作线程发生异常,可以使用 set_exception() 传递给 future。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <iostream> #include <thread> #include <future> #include <exception>
void worker(std::promise<int> p) { try { throw std::runtime_error("计算失败"); p.set_value(100); } catch (...) { p.set_exception(std::current_exception()); } }
int main() { std::promise<int> p; std::future<int> fut = p.get_future();
std::thread t(worker, std::move(p));
try { std::cout << fut.get() << std::endl; } catch (const std::exception& e) { std::cout << "捕获异常: " << e.what() << std::endl; }
t.join();
return 0; }
|
packaged_task
std::packaged_task 可以把一个可调用对象包装成异步任务。
它内部会绑定一个 future。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <iostream> #include <future> #include <thread>
int square(int x) { return x * x; }
int main() { std::packaged_task<int(int)> task(square);
std::future<int> fut = task.get_future();
std::thread t(std::move(task), 6);
std::cout << "结果: " << fut.get() << std::endl;
t.join();
return 0; }
|
输出:
适合场景:
- 任务队列
- 线程池
- 延迟执行任务
- 将函数和结果 future 分离管理
shared_future
普通 std::future 的 get() 只能调用一次。
如果多个线程都需要读取同一个结果,可以使用 std::shared_future。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include <iostream> #include <future> #include <thread> #include <vector>
int compute() { return 123; }
void reader(std::shared_future<int> sf, int id) { std::cout << "线程 " << id << " 获取结果: " << sf.get() << std::endl; }
int main() { std::future<int> fut = std::async(std::launch::async, compute);
std::shared_future<int> sf = fut.share();
std::vector<std::thread> threads;
for (int i = 0; i < 3; ++i) { threads.emplace_back(reader, sf, i); }
for (auto& t : threads) { t.join(); }
return 0; }
|
async、thread、promise 的区别
| 工具 |
主要作用 |
返回值 |
管理难度 |
std::thread |
创建线程执行任务 |
不直接返回 |
较高 |
std::async |
异步执行任务 |
通过 future 返回 |
较低 |
std::promise |
在线程间传递结果 |
配合 future |
中等 |
std::packaged_task |
包装任务 |
配合 future |
中等 |
选择建议
简单异步计算
使用:
需要手动控制线程生命周期
使用:
一个线程向另一个线程传递结果
使用:
1
| std::promise + std::future
|
构建任务队列或线程池
使用: