std::lock_guard 的案例解析(LeetCode 1114. 按序打印)

本文介绍C++11标准库中std::lock_guard类模板的使用,该类模板用于实现线程同步的资源分配时初始化(RAII)方法。文章详细解释了std::lock_guard如何在构造时自动锁定mutex对象,在析构时自动解锁,从而简化了互斥锁的管理,避免了因异常或提前返回导致的未解锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:LeetCode 1114. 按序打印

// std::lock_guard 解法
class Foo {
	public:
	    Foo() {
	        first_lock_.lock();
	        second_lock_.lock();
	    }
	    void first(function<void()> printFirst) {
	        // printFirst() outputs "first". Do not change or remove this line.
	        printFirst();
	        first_lock_.unlock(); 
	    }
	    void second(function<void()> printSecond) {
	        // printSecond() outputs "second". Do not change or remove this line.
	        lock_guard<mutex> lk(first_lock_);
	        printSecond();
	        second_lock_.unlock();
	    }
	    void third(function<void()> printThird) {
	        // printThird() outputs "third". Do not change or remove this line.
	        lock_guard<mutex> lk(second_lock_);
	        printThird();
	    }
	private:
	    mutex first_lock_;
	    mutex second_lock_;
};
  • 互斥类的最重要成员函数是 lock() 和 unlock() 。在进入临界区时,执行 lock() 加锁操作,如果这时已经被其它线程锁住,则当前线程在此排队等待。退出临界区时,执行 unlock() 解锁操作。

  • 更好的办法是采用 ”资源分配时初始化” (RAII) 方法来加锁、解锁,这避免了在临界区中因为抛出异常或 return 等操作导致没有解锁就退出的问题。极大地简化了程序员编写 mutex 相关的异常处理代码。C++11的标准库中提供了std::lock_guard类模板做 mutexRAII

    std::lock_guard 类的构造函数禁用拷贝构造,且禁用移动构造
    std::lock_guard 类除了构造函数和析构函数外没有其它成员函数。
    
  • std::lock_guard 对象构造时,传入的 mutex 对象(即它所管理的 mutex 对象)会被当前线程锁住。在 lock_guard 对象被析构时,它所管理的 mutex 对象会自动解锁,不需要程序员手动调用 lockunlockmutex 进行上锁和解锁操作。

  • lock_guard 对象并不负责管理 mutex 对象的生命周期,lock_guard 对象只是简化了 mutex 对象的上锁和解锁操作,方便线程对互斥量上锁,即在某个 lock_guard 对象的生命周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard 的生命周期结束之后,它所管理的锁对象会被解锁。程序员可以非常方便地使用 lock_guard ,而不用担心异常安全问题。

  • std::lock_guard 在构造时只被锁定一次,并且在销毁时解锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值