C++ 并发与多线程:完整指南

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

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

开始课程

C++ 并发与多线程入门



现代应用程序需要最大性能。C++ 中的并发与多线程能够有效利用多核处理器,加速任务执行。不理解这些概念,就无法创建高负载系统、数据处理程序或游戏引擎。



在本文中,我们将剖析 C++ 多线程的关键机制,从基础的 std::thread 到高级模式。您将学习如何避免数据竞争、正确同步线程以及编写安全的并行代码。



多线程基础:std::thread 和 std::jthread



std::thread 类 (C++11) 是多线程编程的基础。它允许在一个单独的线程中启动一个函数或可调用对象。来看一个最简单的例子:



#include <iostream>#include <thread>

void worker(int id) { std::cout << "线程 " << id << " 开始工作"; std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "线程 " << id << " 完成";}

int main() { std::thread t1(worker, 1); std::thread t2(worker, 2); t1.join(); t2.join(); return 0;}


关键点:

  • join() — 主线程等待子线程完成
  • detach() — 线程独立继续运行(存在资源泄漏风险)
  • std::jthread (C++20) — 在析构函数中自动调用 join()


在调用 join() 之前始终检查 joinable(),以避免重复连接。



线程同步:互斥锁与锁



多线程的主要问题是数据竞争,即多个线程同时修改共享变量。使用互斥锁进行保护。



std::mutex 和 std::lock_guard



#include <iostream>#include <thread>#include <mutex>

std::mutex mtx;int counter = 0;

void increment() { for (int i = 0; i < 100000; ++i) { std::lock_guard<std::mutex> lock(mtx); ++counter; }}

int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "结果: " << counter << ""; // 200000 return 0;}


std::lock_guard 在离开作用域时自动释放互斥锁。如需更灵活的控制,请使用 std::unique_lock。



死锁与 std::scoped_lock



当两个线程互相等待时,就会发生死锁。解决方案是使用 std::scoped_lock (C++17),它可以原子性地锁定多个互斥锁:



std::mutex m1, m2;

void safe_function() { std::scoped_lock lock(m1, m2); // 安全操作两个资源}


并行算法与 std::async



如需执行异步任务而无需手动管理线程,请使用 std::async。它返回一个 std::future,从中可以获取结果。



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

int compute(int n) { std::this_thread::sleep_for(std::chrono::seconds(n)); return n * n;}

int main() { auto future1 = std::async(std::launch::async, compute, 2); auto future2 = std::async(std::launch::async, compute, 3); std::cout << "结果: " << future1.get() << ", " << future2.get() << ""; // 4, 9 return 0;}


启动策略:

  • std::launch::async — 在新线程中启动
  • std::launch::deferred — 延迟执行(在调用 get() 时同步执行)

博客

书籍推荐