news 2026/4/15 14:26:58

C++11 异步编程入门教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++11 异步编程入门教程

1. 概述

C++11 引入了<future>头文件,提供了一套标准化的异步编程工具,用于简化多线程编程和异步任务管理。这套工具主要包括std::futurestd::shared_futurestd::asyncstd::promisestd::packaged_task等组件。

2. std::future

std::future是一个模板类,用于获取异步操作的结果。它代表一个“未来”的值,当异步操作完成后,可以通过它获取结果。

常用接口

  • get(): 获取结果,如果结果未就绪则阻塞等待

  • valid(): 检查 future 是否关联了共享状态

  • wait(): 阻塞等待结果就绪

  • wait_for(): 等待一段时间,返回状态

  • wait_until(): 等待到指定时间点,返回状态

示例代码

#include <iostream> #include <future> #include <thread> #include <chrono> int calculate() { std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时计算 return 42; } int main() { // 启动异步任务 std::future<int> fut = std::async(std::launch::async, calculate); std::cout << "Doing other work..." << std::endl; // 获取结果(会阻塞直到结果就绪) int result = fut.get(); std::cout << "Result: " << result << std::endl; return 0; }

3. std::shared_future

std::shared_futurestd::future的共享版本,可以被多个线程安全地访问。与std::future不同,shared_futureget()方法可以多次调用。

常用接口

  • get(): 获取结果(可多次调用)

  • valid(): 检查是否有效

  • wait(): 等待结果

示例代码

#include <iostream> #include <future> #include <vector> #include <thread> void worker(std::shared_future<int> sf) { // 多个线程可以安全地访问同一个 shared_future int result = sf.get(); std::cout << "Thread " << std::this_thread::get_id() << " got result: " << result << std::endl; } int main() { std::promise<int> prom; std::shared_future<int> sf = prom.get_future(); // 创建多个线程共享同一个 future std::vector<std::thread> threads; for (int i = 0; i < 3; ++i) { threads.emplace_back(worker, sf); } // 设置值 prom.set_value(100); for (auto& t : threads) { t.join(); } return 0; }

4. std::async

std::async是一个函数模板,用于启动异步任务。它返回一个std::future对象,可以通过该对象获取异步任务的结果。

启动策略(std::launch)

  • std::launch::async: 在新线程中异步执行

  • std::launch::deferred: 延迟执行(调用 get() 时执行)

  • std::launch::async | std::launch::deferred: 默认策略,由实现决定

示例代码

#include <iostream> #include <future> #include <chrono> int heavy_computation(int x) { std::this_thread::sleep_for(std::chrono::seconds(1)); return x * x; } int main() { // 异步执行(立即在新线程中启动) auto fut1 = std::async(std::launch::async, heavy_computation, 10); // 延迟执行(调用 get() 时才执行) auto fut2 = std::async(std::launch::deferred, heavy_computation, 20); std::cout << "fut1 is running asynchronously..." << std::endl; // 获取异步结果 int result1 = fut1.get(); std::cout << "Result1: " << result1 << std::endl; // 此时才开始执行 fut2 int result2 = fut2.get(); std::cout << "Result2: " << result2 << std::endl; return 0; }

5. std::promise

std::promise用于在线程之间传递结果。它提供了一个“承诺”,可以在未来某个时间点设置值,并通过关联的std::future获取该值。

常用接口

  • get_future(): 获取关联的 future 对象

  • set_value(): 设置值

  • set_exception(): 设置异常

示例代码

#include <iostream> #include <future> #include <thread> #include <stdexcept> void producer(std::promise<int> prom) { try { std::this_thread::sleep_for(std::chrono::seconds(1)); prom.set_value(42); // 设置结果 } catch (...) { prom.set_exception(std::current_exception()); // 设置异常 } } int main() { std::promise<int> prom; std::future<int> fut = prom.get_future(); std::thread t(producer, std::move(prom)); try { int result = fut.get(); std::cout << "Received result: " << result << std::endl; } catch (const std::exception& e) { std::cout << "Exception: " << e.what() << std::endl; } t.join(); return 0; }

6. std::packaged_task

std::packaged_task是一个可调用对象的包装器,它可以将函数调用与其结果关联起来。类似于std::function,但多了获取 future 的功能。

常用接口

  • get_future(): 获取关联的 future

  • operator(): 执行任务

  • valid(): 检查是否有效

示例代码

#include <iostream> #include <future> #include <thread> int multiply(int x, int y) { return x * y; } int main() { // 包装一个函数 std::packaged_task<int(int, int)> task(multiply); std::future<int> fut = task.get_future(); // 在另一个线程中执行任务 std::thread t(std::move(task), 6, 7); // 获取结果 int result = fut.get(); std::cout << "6 * 7 = " << result << std::endl; t.join(); return 0; }

7. std::future_status

std::future_status是一个枚举类,用于表示等待操作的结果状态。

状态值

  • future_status::ready: 结果已就绪

  • future_status::timeout: 超时(结果未就绪)

  • future_status::deferred: 任务被延迟执行

示例代码

#include <iostream> #include <future> #include <chrono> int slow_function() { std::this_thread::sleep_for(std::chrono::seconds(3)); return 100; } int main() { auto fut = std::async(std::launch::async, slow_function); // 等待 1 秒 auto status = fut.wait_for(std::chrono::seconds(1)); if (status == std::future_status::ready) { std::cout << "Result is ready!" << std::endl; std::cout << "Value: " << fut.get() << std::endl; } else if (status == std::future_status::timeout) { std::cout << "Timeout: result not ready yet" << std::endl; } else if (status == std::future_status::deferred) { std::cout << "Task is deferred" << std::endl; } // 最终获取结果 std::cout << "Final result: " << fut.get() << std::endl; return 0; }

8. 综合示例:生产者-消费者模式

#include <iostream> #include <future> #include <thread> #include <queue> #include <mutex> #include <condition_variable> template<typename T> class ThreadSafeQueue { private: std::queue<T> queue_; std::mutex mutex_; std::condition_variable cond_; public: void push(T value) { std::lock_guard<std::mutex> lock(mutex_); queue_.push(std::move(value)); cond_.notify_one(); } T pop() { std::unique_lock<std::mutex> lock(mutex_); cond_.wait(lock, [this]{ return !queue_.empty(); }); T value = std::move(queue_.front()); queue_.pop(); return value; } }; void producer(ThreadSafeQueue<std::promise<int>>& queue, int count) { for (int i = 0; i < count; ++i) { std::promise<int> prom; auto fut = prom.get_future(); queue.push(std::move(prom)); // 模拟生产耗时 std::this_thread::sleep_for(std::chrono::milliseconds(100)); prom.set_value(i * i); // 设置结果 } } void consumer(ThreadSafeQueue<std::promise<int>>& queue, int count) { for (int i = 0; i < count; ++i) { auto prom = queue.pop(); auto fut = prom.get_future(); int result = fut.get(); std::cout << "Consumed: " << result << std::endl; } } int main() { ThreadSafeQueue<std::promise<int>> queue; std::thread prod(producer, std::ref(queue), 5); std::thread cons(consumer, std::ref(queue), 5); prod.join(); cons.join(); return 0; }

9. 总结

  • future/promise: 最基本的异步结果传递机制

  • async: 最简单的异步任务启动方式

  • packaged_task: 包装可调用对象,便于线程池使用

  • shared_future: 支持多个消费者共享结果

  • future_status: 用于非阻塞的状态检查

这套工具使得 C++ 异步编程更加标准化和安全,避免了直接操作线程和锁的复杂性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 5:51:51

数字图像处理篇---场模糊

核心比喻&#xff1a;透过“不均匀的流动介质”看东西想象两个场景&#xff1a;夏天看远处的地面&#xff0c;热空气上升&#xff0c;让景象扭曲、抖动、模糊。透过毛玻璃或磨砂玻璃&#xff0c;但玻璃的粗糙程度不均匀&#xff0c;有的地方磨得厉害&#xff08;很模糊&#xf…

作者头像 李华
网站建设 2026/4/12 19:51:36

数字图像处理篇---JPEG2000

核心比喻&#xff1a;从“马赛克拼图”到“水彩晕染”还记得JPEG是把图切成8x8的小块&#xff08;马赛克&#xff09;单独处理吗&#xff1f;这带来了“块状伪影”的问题。 JPEG2000放弃了“切块”思路&#xff0c;改用了一种更先进、更连续的方法——小波变换。想象你要临摹一…

作者头像 李华
网站建设 2026/4/10 22:30:03

小程序毕设项目:基于springboot+小程序的高校校园信息交流平台小程序设计与实现(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/10 17:16:01

计算机小程序毕设实战-基于SpringBoot中小学家校通系统的设计与实现springboot+小程序的家校通程序设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/12 8:17:31

(100分)- 幻方修复(Java JS Python)

(100分)- 幻方修复&#xff08;Java & JS & Python&#xff09; 题目描述 幻方&#xff08;Magic Square&#xff09;是一个由1~N&#xff0c;共N个整数构成的N*N矩阵&#xff0c;满足每行、列和对角线上的数字和相等。 上回你已经帮助小明将写错一个数字的幻方进行…

作者头像 李华
网站建设 2026/3/30 23:43:04

STC15F204EA概述

特性:增强型 8051 CPU&#xff0c;1T&#xff0c;单时钟/机器周期&#xff0c;速度比普通8051快6-12倍工作电压&#xff1a;STC15F204EA 系列工作电压&#xff1a;5.5V - 3.8V&#xff08;5V 单片机&#xff09;STC15L204EA 系列工作电压&#xff1a;3.6V - 2.4V&#xff08;3V…

作者头像 李华