首页 > 代码库 > Linux封装之四:RAII实现MutexLock自动化解锁
Linux封装之四:RAII实现MutexLock自动化解锁
在实现线程的过程中,我们经常会写类似于这样的代码:
{ mutex_.lock(); //XXX if(...) 语句; //XXX mutex_.unlock();}
虽然这段代码是正常的加锁解锁,但是有时候我们难免会出现一些低级错误,例如把 忘了写mutex_.unlock()。那么我们该如何防止这种错误呢? 我们可以采用和实现智能指针相似的办法,把加锁和解锁封装在同一个对象中。
实现“对象生命期”等于“加锁、解锁周期” 。
代码如下;
1 //类的关联 2 class MutexGuard:NonCopyable 3 { 4 public: 5 MutexGuard(MutexLock &mutex)//no copy no assignment 6 :mutex_(mutex) 7 { mutex_.lock(); } 8 9 ~MutexGuard()10 { mutex_.unlock(); } 11 12 private:13 MutexLock &mutex_;//attention ,这里M类不存在copy,assignment能力故引用之 14 };
这样 我们就把资源的获取(加锁)放在构造函数,把资源的释放(解锁)放在析构函数中,这种做法就是C++中的RAII技术。
这里我们给出RAII的解释:RAII,也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源、避免内存泄露的方法。它保证在任何情况下,使用对象时先构造对象,最后析构对象。
这对于我们编写简洁优雅的代码,好处是显而易见的。
以下这个程序实现的是计算Buffer是否为空,一般我们会这样写:
1 bool Buffer::isEmpty()const2 {3 bool flag = false;4 mutex_lock();5 flag = q_.empty();6 mutex_.unlock();7 return flag;8 }
这段代码实在称不上美观,但是我们使用MutexGuard之后,我们的代码就变为:
bool Buffer::isEmpty()const{//after MutexGuard lock(mutex_);//作用域仅限于花括号内,随后自动调用析构函数,放锁 return q_.empty();}
这是否美观了许多?
当然,我们有时候会犯这种错误,忘记声明MutexGuard的对象,例如:
bool Buffer::isEmpty()const{ MutexGuard mutex_);//wrong return q_.empty();}
为了防止这种错误,我们增加了一个宏:
#define MutexGuard(m) "Error MutexGuard"
这样,当我们错误使用的时候,就会导致编译错误,可以帮助我们早些发现问题。
Linux封装之四:RAII实现MutexLock自动化解锁
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。