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

📅 发布时间:2026/7/9 23:30:43 👁️ 浏览次数:
C++11 异步编程入门教程
1. 概述C11 引入了future头文件提供了一套标准化的异步编程工具用于简化多线程编程和异步任务管理。这套工具主要包括std::future、std::shared_future、std::async、std::promise、std::packaged_task等组件。2. std::futurestd::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::futureint 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_futurestd::shared_future是std::future的共享版本可以被多个线程安全地访问。与std::future不同shared_future的get()方法可以多次调用。常用接口get(): 获取结果可多次调用valid(): 检查是否有效wait(): 等待结果示例代码#include iostream #include future #include vector #include thread void worker(std::shared_futureint sf) { // 多个线程可以安全地访问同一个 shared_future int result sf.get(); std::cout Thread std::this_thread::get_id() got result: result std::endl; } int main() { std::promiseint prom; std::shared_futureint sf prom.get_future(); // 创建多个线程共享同一个 future std::vectorstd::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::asyncstd::async是一个函数模板用于启动异步任务。它返回一个std::future对象可以通过该对象获取异步任务的结果。启动策略std::launchstd::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::promisestd::promise用于在线程之间传递结果。它提供了一个“承诺”可以在未来某个时间点设置值并通过关联的std::future获取该值。常用接口get_future(): 获取关联的 future 对象set_value(): 设置值set_exception(): 设置异常示例代码#include iostream #include future #include thread #include stdexcept void producer(std::promiseint 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::promiseint prom; std::futureint 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_taskstd::packaged_task是一个可调用对象的包装器它可以将函数调用与其结果关联起来。类似于std::function但多了获取 future 的功能。常用接口get_future(): 获取关联的 futureoperator(): 执行任务valid(): 检查是否有效示例代码#include iostream #include future #include thread int multiply(int x, int y) { return x * y; } int main() { // 包装一个函数 std::packaged_taskint(int, int) task(multiply); std::futureint 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_statusstd::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 templatetypename T class ThreadSafeQueue { private: std::queueT queue_; std::mutex mutex_; std::condition_variable cond_; public: void push(T value) { std::lock_guardstd::mutex lock(mutex_); queue_.push(std::move(value)); cond_.notify_one(); } T pop() { std::unique_lockstd::mutex lock(mutex_); cond_.wait(lock, [this]{ return !queue_.empty(); }); T value std::move(queue_.front()); queue_.pop(); return value; } }; void producer(ThreadSafeQueuestd::promiseint queue, int count) { for (int i 0; i count; i) { std::promiseint 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(ThreadSafeQueuestd::promiseint 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() { ThreadSafeQueuestd::promiseint 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 异步编程更加标准化和安全避免了直接操作线程和锁的复杂性。