C++异步编程:完整指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 中的异步编程:从 std::async 到协程



C++ 中的异步编程是创建高性能和响应式应用程序的强大工具。在现代世界中,多核处理器已成为标准,高效管理并行任务的能力是每位 C++ 开发者的必备技能。本文将讲解关键概念,从标准库的基本机制开始,一直到 C++20 的现代协程。



为什么需要异步编程?

异步编程的主要目标是不阻塞程序的主执行线程。想象一下,你的应用程序需要从网络下载一个文件,对其进行处理,然后展示给用户。如果你同步执行这些操作,界面会在下载期间"卡住"。异步方法允许你在"后台"运行一个耗时操作,同时主线程继续处理用户输入。



C++ 中异步的基本方法

在 C++ 中,有几种实现异步执行的方式:

  • 手动线程管理(std::thread) — 一种低级但灵活的方法。
  • std::async 和 std::future — 用于启动异步任务的高级机制。
  • std::packaged_task 和 std::promise — 用于更精细的控制。
  • 协程(C++20) — 编写异步代码的现代而优雅的方式。


使用 std::async 和 std::future

这是启动异步任务最简单的方式。std::async 函数返回一个 std::future 对象,该对象将包含执行结果。



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

int heavy_computation(int x) { std::this_thread::sleep_for(std::chrono::seconds(2)); return x * x;}

int main() { std::cout << "正在启动异步任务..."; std::future<int> result = std::async(std::launch::async, heavy_computation, 42); // 在任务运行期间做其他事情 std::cout << "主线程未被阻塞!"; // 获取结果(如果任务尚未完成,则阻塞) int value = result.get(); std::cout << "结果: " << value << ""; return 0;}


std::launch::async 标志保证任务将在单独的线程中执行。如果未指定,实现可能会将执行延迟到调用 .get() 时。



使用 std::promise 和 std::packaged_task

这些机制提供了更多的控制。std::promise 允许你"承诺"一个稍后设置的值,而 std::packaged_task 将一个可调用对象包装成一个任务。



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

void set_value(std::promise<int>&& prom) { std::this_thread::sleep_for(std::chrono::seconds(1)); prom.set_value(100);}

int main() { std::promise<int> prom; std::future<int> fut = prom.get_future(); std::thread t(set_value, std::move(prom)); std::cout << "正在等待结果..."; int value = fut.get(); std::cout << "收到: " << value << ""; t.join(); return 0;}


重要提示: std::promise 和 std::future 是仅可移动的对象。它们不能被复制,只能被移动。



C++20 中的协程:异步的新层次

协程是可以暂停执行并在稍后恢复的函数。它们允许你像编写同步代码一样编写异步代码。



基本

博客

书籍推荐