当前位置: 首页 > news >正文

C++ 异步编程 并发编程技术

C++ 异步编程是一种并发编程技术,用于通过非阻塞的方式执行任务。与传统的同步编程相比,异步编程可以提高程序的效率,尤其是在处理 I/O 操作、网络请求或多线程任务时,避免主线程等待任务完成。

1. 异步编程的基本概念

异步编程主要解决如何在不阻塞主线程的情况下,执行耗时的任务,并在任务完成时以某种方式通知或继续执行程序的其他部分。在 C++ 中,异步编程的主要机制包括:

多线程(Threading):通过多线程来实现并行执行任务。
异步任务(Asynchronous Task):通过 std::future 和 std::promise 等方式执行异步任务。
事件循环和回调(Event Loop & Callbacks):通过事件触发器在任务完成后执行相应的回调函数。
异步编程的主要目标是:

提高程序的响应性,尤其是 UI 程序或网络服务。
更好地利用系统资源,避免线程或 CPU 被阻塞在等待上。

2. C++ 中的异步编程工具

C++11 引入了大量支持异步编程的库和工具,使得 C++ 异步编程变得更加易用和标准化。以下是 C++ 异步编程的几种主要方式:

2.1. std::thread

std::thread 是 C++ 中用来创建和管理线程的基本工具。线程使得多个任务能够并发运行。

  • 创建线程:
#include <iostream>
#include <thread>void task(int n) {std::cout << "Task " << n << " is running in a separate thread.\n";
}int main() {std::thread t(task, 10);t.join();  // 等待线程 t 执行完成return 0;
}
  • 线程的生命周期:
join():等待线程执行完毕,阻塞主线程直到子线程结束。
detach():让线程在后台运行,主线程不等待其完成。
使用 std::thread 虽然可以实现简单的并发任务,但对于复杂的异步任务管理,需要更高层次的抽象,如 std::async。

2.2. std::async 和 std::future

std::async 是 C++11 提供的更高层的异步编程接口。它可以创建一个异步任务,并返回一个 std::future 对象来获取异步任务的结果。

  • 异步任务的执行:
#include <iostream>
#include <future>
#include <thread>int long_computation(int n) {std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟长时间计算return n * n;
}int main() {// 创建一个异步任务std::future<int> result = std::async(std::launch::async, long_computation, 10);// 执行其他任务std::cout << "Doing other things while waiting...\n";// 获取异步任务的结果int value = result.get();  // 这个操作会阻塞主线程直到结果准备好std::cout << "Result is " << value << "\n";return 0;
}
  • std::async 的模式:

std::launch::async:强制在新线程中异步执行。
std::launch::deferred:任务不会立即执行,只有调用 get() 或 wait() 时才会执行。
std::future 是 std::async 的返回类型,用于表示一个异步操作的结果。它提供以下几个重要的方法:

get():阻塞主线程直到任务完成并返回结果。
wait():阻塞主线程,直到任务完成,但不返回结果。
wait_for() 和 wait_until():允许设置等待超时,检查任务是否完成。

2.3. std::promise 和 std::future

std::promise 和 std::future 是 C++ 提供的另一组异步任务管理工具。std::promise 用于设置异步操作的结果,而 std::future 用于获取结果。

  • std::promise 和 std::future 的用法:
#include <iostream>
#include <thread>
#include <future>void calculate_square(std::promise<int>&& p, int n) {int result = n * n;std::this_thread::sleep_for(std::chrono::seconds(2));p.set_value(result);  // 设置结果
}int main() {std::promise<int> p;  // 创建 promise 对象std::future<int> result = p.get_future();  // 获取 future// 启动线程并将 promise 对象传递进去std::thread t(calculate_square, std::move(p), 10);// 主线程做其他事情std::cout << "Waiting for result...\n";// 获取结果(会阻塞主线程)int value = result.get();std::cout << "Result is " << value << "\n";t.join();return 0;
}

这种方式适用于更加复杂的异步任务场景,特别是当你需要手动控制任务的开始和结束时。

2.4. std::packaged_task

std::packaged_task 是 C++11 提供的一种将任务打包为可异步调用的工具。它可以与 std::future 一起使用,允许我们将函数、lambda 表达式等包装为异步任务。

  • std::packaged_task 示例:
#include <iostream>
#include <future>
#include <thread>int compute_sum(int a, int b) {return a + b;
}int main() {std::packaged_task<int(int, int)> task(compute_sum);  // 打包任务std::future<int> result = task.get_future();  // 获取 future 对象std::thread t(std::move(task), 5, 7);  // 启动线程,传入参数std::cout << "Result: " << result.get() << "\n";  // 获取结果t.join();return 0;
}

2.5. std::mutex、std::lock_guard 和 std::unique_lock

在异步编程或多线程编程中,保护共享资源免受并发访问是至关重要的。C++ 提供了 std::mutex(互斥量)来保护共享数据。std::lock_guard 和 std::unique_lock 提供了自动锁定和解锁的机制,避免手动管理锁的复杂性。

  • 使用 std::mutex 进行线程同步:
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;  // 互斥量保护共享资源void print_message(const std::string& message) {std::lock_guard<std::mutex> lock(mtx);  // 自动加锁和解锁std::cout << message << std::endl;
}int main() {std::thread t1(print_message, "Hello from thread 1");std::thread t2(print_message, "Hello from thread 2");t1.join();t2.join();return 0;
}

std::unique_lock 的灵活性: std::unique_lock 比 std::lock_guard 更加灵活,支持延迟加锁、手动解锁等操作。

std::unique_lock<std::mutex> lock(mtx);
lock.unlock();  // 手动解锁
lock.lock();    // 手动加锁

3. C++ 异步编程的实际应用场景

C++ 的异步编程在以下几种场景中有着广泛的应用:

3.1. 高性能 I/O

异步 I/O 操作避免了主线程的阻塞,特别是在高并发的网络服务中,通过异步操作处理大量的请求可以显著提高吞吐量。

3.2. 并行计算

对于计算密集型任务,使用多线程或异步任务将计算拆分为多个并发执行的任务,能够更有效地利用多核 CPU 提升性能。

3.3. 事件驱动编程

在 GUI 或服务器编程中,异步编程能够避免用户界面或服务器的主线程被阻塞,从而保持系统的响应性。

4. 总结

C++ 提供了多种异步编程工具,从基本的 std::thread 到更高级的 std::async 和 std::future。异步编程可以显著提高程序的效率,特别是在 I/O 密集型和计算密集型任务中。熟悉这些工具的使用,能够帮助开发者编写出更高效、响应更快的程序。


http://www.mrgr.cn/news/43483.html

相关文章:

  • C语言入门基础题(力扣):完成旅途的最少时间(C语言版)
  • CGLib动态代理和JDK动态代理Demo、ASM技术尝鲜
  • AbMole牛磺胆酸钠在构建大鼠急性胰腺炎模型中的应用
  • 环境可靠性
  • COPS论文总结——Lec17
  • 信息安全工程师(34)访问控制模型
  • 乌班图基础设施安装之Mysql8.0+Redis6.X安装
  • 前端的全栈混合之路Meteor篇(一):运行在浏览器端的数据库-MiniMongo介绍及其前后端数据实时同步示例
  • 数学建模 第四讲 - 数学规划模型
  • Python学习笔记-函数
  • 【网络篇】计算机网络——应用层详述(笔记)
  • Java 网络编程基础
  • 【408计算机考研课程】数据结构-数据结构在学什么?
  • 二叉树的中序&后序遍历——非递归版本
  • 【C语言】分支与循环
  • 矩阵求解复数(aniwoth求解串扰)
  • 基金好书入门阅读笔记《基金作战笔记:从投基新手到配置高手的进阶之路》1
  • mybatis分页拦截器
  • 基于H3C环境的实验——OSPF
  • 字节跳动收购Oladance耳机:强化音频技术,加速VR/AR生态布局