C++ 异步编程简介
现代应用程序越来越需要高性能和响应性。C++ 中的异步编程是一种强大的工具,它允许在不阻塞主执行流的情况下同时执行多个任务。在本指南中,我们将讲解 C++ 异步编程的基础知识:从经典方法到 C++20 标准中添加的现代协程 (coroutines)。
如果您是 C++ 新手,但已经熟悉基本语法,本文档将帮助您理解如何让程序同时处理多项任务。我们将介绍可以立即在项目中使用的实用示例。
核心概念及其必要性
在传统的同步编程中,代码严格按顺序执行:一个操作完成后,下一个操作才开始。这很简单,但如果程序正在等待 I/O(读取文件、网络请求)或执行繁重计算,效率会很低。
异步编程解决了这个问题,它允许:
- 不阻塞主线程 — 保持应用程序界面的响应性。
- 加速执行 — 在多核处理器上并行处理数据。
- 高效利用资源 — 当一个任务在等待数据时,另一个任务可以执行。
在 C++ 中,有几种方法可以实现异步:从底层线程 (std::thread) 到高级抽象 (std::async、std::future 和协程)。
1. 使用 std::async 和 std::future 实现异步
在 C++ 中启动异步任务的最简单方法是使用头文件 <future> 中的 std::async 函数。它返回一个 std::future 对象,该对象存储执行结果。
基本示例
#include <iostream>#include <future>#include <thread>#include <chrono>
// 将要异步执行的函数int slow_calculation(int x) { std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟长时间工作 return x * x;}
int main() { std::cout << "启动异步任务..." << std::endl; // 在单独的线程中启动 slow_calculation std::future<int> result = std::async(std::launch::async, slow_calculation, 5); std::cout << "主线程继续工作..." << std::endl; // 获取结果(如果任务尚未完成,则阻塞线程) int value = result.get(); std::cout << "结果: " << value << std::endl; // 输出: 25 return 0;}在这个示例中,std::async 在单独的线程中启动函数。当函数执行时,主线程输出一条消息。方法 get() 等待任务完成并返回结果。
启动策略
std::async 有两种模式:
std::launch::async— 任务保证在新线程中执行。std::launch::deferred— 任务延迟执行,仅在调用get()或wait()时在同一个线程中执行。
2. Promises 和 Futures:手动管理
如果您需要对异步任务进行更灵活的管理,请使用 std::promise 和 std::future 对。promise 允许在一个线程中设置值或异常,而 future 允许在另一个线程中获取它。
使用 promise 的示例
#include <iostream>#include <future>#include <thread>
void worker(std::promise<int> prom, int a, int b) { try { int result = a / b; // 可能