c++ std::lock_guard 深入解析

📅 发布时间:2026/7/7 7:40:59 👁️ 浏览次数:
c++ std::lock_guard 深入解析
在多线程编程中确保线程安全是一个关键问题。std::lock_guard是 C 标准库中提供的一种 RAIIResource Acquisition Is Initialization机制用于自动管理互斥锁的加锁和解锁操作。本文将首先展示一个简化的std::lock_guard源码实现然后详细解释其工作原理并通过一个示例进一步说明如何使用std::lock_guard。1. 简化的std::lock_guard源码实现以下是std::lock_guard的简化源码实现代码语言cppAI代码解释template typename Mutex class lock_guard { public: using mutex_type Mutex; // 普通构造函数构造时加锁 explicit lock_guard(Mutex m) : m_(m) { m_.lock(); } // 带adopt_lock参数的构造函数构造时不加锁 lock_guard(Mutex m, std::adopt_lock_t) noexcept : m_(m) {} // 析构函数析构时解锁 ~lock_guard() noexcept { m_.unlock(); } // 禁止拷贝构造和赋值操作 lock_guard(const lock_guard) delete; lock_guard operator(const lock_guard) delete; private: Mutex m_; // 保存对互斥锁的引用 };2. 代码解释2.1 构造函数普通构造函数explicit lock_guard(Mutex m) : m_(m) { m_.lock(); }接受一个互斥锁对象的引用m并将其保存在成员变量m_中。在构造时调用互斥锁的lock()方法对互斥锁进行加锁。带adopt_lock参数的构造函数lock_guard(Mutex m, std::adopt_lock_t) noexcept : m_(m) {}同样接受一个互斥锁对象的引用m但不会在构造时加锁。这种构造方式通常用于当互斥锁已经被当前线程加锁但需要lock_guard在作用域结束时自动解锁的情况。2.2 析构函数代码语言cppAI代码解释~lock_guard() noexcept { m_.unlock(); }在lock_guard对象析构时调用互斥锁的unlock()方法释放互斥锁。2.3 禁止拷贝构造和赋值操作代码语言cppAI代码解释lock_guard(const lock_guard) delete; lock_guard operator(const lock_guard) delete;通过将拷贝构造函数和赋值操作符函数声明为删除函数禁止lock_guard对象的拷贝和赋值操作。这是因为互斥锁的管理是基于对象生命周期的如果允许拷贝或赋值可能会导致多个lock_guard对象同时管理同一个互斥锁从而引发潜在的线程安全问题。2.4 私有成员变量代码语言cppAI代码解释Mutex m_; // 保存对互斥锁的引用m_是一个对互斥锁的引用用于在构造和析构时操作互斥锁。3. 示例说明为了进一步说明如何使用std::lock_guard我们通过一个示例来展示其在多线程环境中的使用。假设我们有一个共享的资源sharedResource需要多个线程安全地对其进行访问和修改。示例代码代码语言cppAI代码解释#include iostream #include mutex #include thread #include vector std::mutex mtx; int sharedResource 0; void threadFunction(int id) { for (int i 0; i 10000; i) { std::lock_guardstd::mutex lock(mtx); // 自动加锁 sharedResource id; // 当 lock 的作用域结束时自动解锁 } } int main() { std::vectorstd::thread threads; for (int i 0; i 10; i) { threads.emplace_back(threadFunction, i); } for (auto thread : threads) { thread.join(); } std::cout sharedResource: sharedResource std::endl; return 0; }示例解释共享资源sharedResource是一个全局变量多个线程将对其进行访问和修改。线程函数threadFunction是线程执行的函数每个线程会将sharedResource增加id的值重复 10000 次。在每次修改sharedResource之前使用std::lock_guard对互斥锁mtx进行加锁确保同一时间只有一个线程可以访问sharedResource。线程创建和同步在main函数中创建了 10 个线程每个线程执行threadFunction。使用std::thread::join确保所有线程完成执行后主线程继续运行。输出结果最终sharedResource的值将被正确计算并输出。示例输出假设每个线程的id从 0 到 9每个线程将sharedResource增加id的值 10000 次最终sharedResource的值将是代码语言txtAI代码解释sharedResource: 4500004. 总结std::lock_guard是 C 标准库中提供的一种 RAII 机制用于自动管理互斥锁的加锁和解锁操作。通过构造函数和析构函数的自动调用std::lock_guard确保互斥锁在作用域结束时自动释放从而避免因忘记解锁而导致的死锁问题。合理使用std::lock_guard可以有效提高多线程程序的稳定性和可靠性。通过本文的简化源码实现、代码解释和示例说明希望读者能够更好地理解和应用std::lock_guard。在实际编程中合理使用同步机制可以有效避免数据竞争和未定义行为提高程序的稳定性和可靠性。