我们不止一次写过这种代码:

{
mutex_.lock();
//XXX
if(....)
return; //XXX
mutex_.unlock();
}

显然,这段代码中我们忘记了解锁。那么如何防止这种情况,我们采用和智能指针相同的策略,把加锁和解锁的过程封装在一个对象中。

实现“对象生命期”等于“加锁周期”。

代码如下:

class MutexLockGuard : NonCopyable
{
public:
MutexLockGuard(MutexLock &mutex) :mutex_(mutex)
{ mutex_.lock(); }
~MutexLockGuard()
{ mutex_.unlock(); }
private:
MutexLock &mutex_;
};

这种把资源获取放在构造函数、资源释放放入析构函数中的做法,就是C++中的RAII技术,“资源获取即初始化”。它巧妙在C++中的栈对象是一定会析构的,所以资源一定会被释放。

这个类对于我们编写优雅的代码,好处是显而易见的,例如:

size_t Buffer::size() const
{
mutex_.lock();
int ret = queue_.size();
mutex_.unlock();
return queue_.size();
}

这段代码实在称不上美观,但是有了MutexLockGuard,我们可以写出:

size_t Buffer::size() const
{
MutexLockGuard lock(mutex_);
return queue_.size();
}

代码的美观性提高了许多。

当然,有一种使用方式是错误的,例如:

size_t Buffer::size() const
{
MutexLockGuard(mutex_);
return queue_.size();
}

这段代码的加锁周期仅限于那一行,为了防止错误使用,我们增加一个宏:

#define MutexLockGuard(m) "Error MutexLockGuard"

这样当错误使用的时候,会导致编译错误,使得我们早些发现问题。

最新文章

  1. Android 学习资源收集
  2. 查看SQLserver编码格式的SQL语句
  3. Quartz2D 编程指南(二)变换、图案、阴影
  4. maven依赖关系中Scope的作用
  5. jQuery操作json数据
  6. HTML DOM事件
  7. Codevs 2875 RY哥查字典
  8. OpenSessionInViewFilter 的配置及替代方案(转)
  9. 【开源java游戏框架libgdx专题】-11-核心库-演员类
  10. 介绍一款替代SSMS的sqlserver管理工具 toad for sqlserver5.7
  11. php获取脚本执行的参数
  12. Linux SVN服务器的搭建配置及分支的创建与合并
  13. (一)走进Metasploit渗透测试框架
  14. Entity Framework Core系列之DbContext(删除)
  15. 【java】:多线程面试题
  16. java 基础之--类加载器的过程
  17. Jquery学习(表单-Button)-----jQuery1.4.2
  18. [开源] .NET数据库ORM类库 Insql
  19. (转)谈谈RTP传输中的负载类型和时间戳
  20. Python3基础 map+lambda 将指定系列元素乘2

热门文章

  1. Mysql性能优化【转】
  2. centos 7 编译mod_security
  3. source insight setting
  4. 非常好!!!Linux源代码阅读——中断【转】
  5. 自己写操作系统 2 - 安装bochs虚拟机
  6. 学习PHP注意事项
  7. “玲珑杯”ACM比赛 Round #1
  8. ZOJ 3937 More Health Points (2016 浙江省赛 B题,可持久维护凸壳)
  9. 状压DP【p1879】[USACO06NOV]玉米田Corn Fields
  10. ELK之收集日志到mysql数据库