多线程程序中为了防止线程并发造成的竞态,需要经常使用到Mutex进行数据保护。posix提供了phtread_mutex_t进行互斥保护数据。Mutex的使用需要初始化和释放对应(phtread_mutex_init() 和 phtread_mutex_destroy() 对应),上锁和解锁对应(phtread_mutex_lock 和 pthread_mutex_unlock对应)。lock和unlock的过程是设计逻辑的一部分一般都程序员都能正确的进行加锁和解锁对应,但是要防止lock之后程序出现异常或者提前return而没有unlock。初始化mutex之后不释放也会造成资源泄漏,也是很容易遗漏的地方。在实际开发中一般都需要自己封装一下Mutex。

class MutexLock
{
public:
MutexLock() : holder_(0)
{
int ret = pthread_mutex_init(&mutex_, NULL);
assert(ret == 0);
} ~MutexLock()
{
assert(holder_ == 0);
int ret = pthread_mutex_destroy(&mutex_);
assert(ret == 0);
} bool isLockedByThisThread() const
{
return holder_ == static_cast<pid_t>(::syscall(SYS_gettid));
} void assertLocked() const
{
assert(isLockedByThisThread());
} void lock()
{
pthread_mutex_lock(&mutex_);
assignHolder();
} void unlock()
{
unassignHolder();
pthread_mutex_unlock(&mutex_);
} pthread_mutex_t* getPthreadMutex()
{
return &mutex_;
} private: MutexLock(const MutexLock &);
MutexLock &operator=(const MutexLock &); void unassignHolder()
{
holder_ = 0;
} void assignHolder()
{
holder_ = static_cast<pid_t>(::syscall(SYS_gettid));
} pthread_mutex_t mutex_;
pid_t holder_;
}; class MutexLockGuard
{
public:
explicit MutexLockGuard(MutexLock& mutex)
: mutex_(mutex)
{
mutex_.lock();
} ~MutexLockGuard()
{
mutex_.unlock();
} private:
MutexLockGuard(const MutexLockGuard &);
MutexLockGuard &operator=(const MutexLockGuard &); MutexLock& mutex_;
};

  为了提高MutextLock的易用性,增加了一个MutexLockGuard 类来封装MutextLock,实际使用的时候直接使用MutexLockGuard,这样就能防止忘记释放Mutex的情况出现(MutexLockGuard 超出作用域(一般是一个栈上变量)就会自动释放,调用析构函数,destroy掉mutex)。

  以上封装其实就是所谓的RAII的一个具体实践,C++中的智能指针shared_ptr,weak_ptr,unique_ptr 也是RAII的优秀实现。

  注:其实在C++11 线程库中已经有lock guard可以直接使用了(std::lock_guard ,只需要include<mutex>),不需要自己再写一遍,对于没有迁移到C++11上的项目可以使用自己封装的Mutex来提高易用性。

C++ 封装互斥对象的更多相关文章

  1. 用C语言封装OC对象(耐心阅读,非常重要)

    用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...

  2. hibernate将本地SQL查询结果封装成对象

    hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...

  3. 互斥对象 Mutex 和MFC中的CMutex

    互斥(Mutex)是一种用途非常广泛的内核对象.能够保证多个线程对同一共享资源的互斥访问.同临界区有些类似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共 ...

  4. Windows多线程同步系列之一-----互斥对象

    多线程同步之互斥对象 作者:vpoet mail:vpoet_sir@163.com   对卖票问题进行线程间同步,本文将在上文的基础上,使用互斥对象对线程进行同步. 首先看看windows API ...

  5. c++多线程编程之互斥对象(锁)的使用之----死锁

    一.死锁会在什么情况发生 1.假设有如下代码 mutex;   //代表一个全局互斥对象 void  A() { mutex.lock(); //这里操作共享数据 B();  //这里调用B方法 mu ...

  6. XML解析之sax解析案例(二)使用sax解析把 xml文档封装成对象

    Demo1类: import java.io.File; import java.util.List; import javax.xml.parsers.SAXParser; import javax ...

  7. Spring 将请求参数封装成对象

    简单描述:最近手里的模块,前后台之间需要传递很多的参数,使用封装的PageData,来获取请求参数的,作微服务迁移的时候,就涉及到需要把参数从pagedata里取出来,一个一个的放到对象的属性中.就很 ...

  8. c++11の数据竞争和互斥对象

    一.数据竞争的产生 在下面例子中: void function_1() { ; i < ; i++) { std::cout << "from function 1:&qu ...

  9. 通过反射将request中的参数封装到对象中

    import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.text.SimpleDateFo ...

随机推荐

  1. Swift入门篇-字符串和字符

    今天主要是介绍一下字符串的用法 ,字符串的语法和object-c语法不太一样,但是思想是一样,就是写法不太一样.如果您对.net和java语法比较熟悉的话,那您几乎没有深压力.如果您对swift 基本 ...

  2. Oracle中的索引详解

    Oracle中的索引概述 索引与表一样,也属于段(segment)的一种.里面存放了用户的数据,跟表一样需要占用磁盘空间.索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是 ...

  3. COM是一个更好的C++

    昨天看了<COM本质论>的第一章”COM是一个更好的C++”,觉得很有必要做一些笔记,于是整理成这篇文章,我相信你值得拥有. 这篇文章主要讲的内容是:一个实现了快速查找功能的类FastSt ...

  4. maven eclipse miss required library解决

    我是直接到C:\Users\admin\.m2\repository目录把所有的库包全删除,然后在项目里刷新一下,搞定!

  5. C#人爱学不学9[C#5.0异步实例+WPF自己的MVVM Async应用 1/12]

    文章摘要: 1. 通过简单DEMO.让读者理解Task和Task<T>    学习过程中,掌握async和await 2. 理解同步和异步的执行 3. Task.Factory.Start ...

  6. 启动Eclipse 弹出“Failed to load the JNI shared library”错误的解决方法

    原因1:eclipse的版本与jre或者jdk版本不一致 对策:要么两者都安装64位的,要么都安两个是32位一个是64位. 原因2:给定目录下jvm.dll不存在 对策:(1)重新安装jre或者jdk ...

  7. 巧用css border

    上下左右边框交界处呈现平滑的斜线.利用这个特点,通过设置不同的上下左右边框宽度或颜色,可以得到小三角.梯形等. 调整宽度大小可以调节三角形形状. 实现三角形 示例1: #test1{ height:2 ...

  8. LCLFramework框架 1.1 Pre-Alpha 源码公布

    使用开发框架的好处:1.框架在技术上为软件系统提供了完整的模式实践2.框架为团队提供了合理可行的软件开发过程模式3.框架的应用大大提高了团队的开发效率,团队只需要关注与领域相关的业务实现,而无需关注具 ...

  9. This application is currently offline. To enable the application, remove the app_offline.htm file from the application r

    退出VS ,把程序中主目录里的app_offline.htm文件删除,重新启动VS 就可以了.

  10. [原创]Java中的字符串比较,按照使用习惯进行比较

    java中的字符串比较一般可以采用compareTo函数,如果a.compareTo(b)返回的是小于0的数,那么说明a的unicode编码值小于b的unicode编码值. 但是很多情况下,我们开发一 ...