多线程程序中为了防止线程并发造成的竞态,需要经常使用到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. raspberry pi 如何汉化显示中文

    1 树莓派初装系统之后,首次启动会出现“raspi-config”工具,如下图:(若不是初次启动,在命令模式下,请输入 sudo raspi-config 命令,即可调出此界面.若在图形桌面下,打开桌 ...

  2. RabbitMQ的工作队列和路由

    工作队列:Working Queue   工作队列这个概念与简单的发送/接收消息的区别就是:接收方接收到消息后,可能需要花费更长的时间来处理消息,这个过程就叫一个Work/Task.   几个概念 分 ...

  3. CoreOS实践(1)—CoreOS初体验

    CoreOS主要包含以下一些东西: (1)最小的OS:kernel+systemd (2)使用Docker运行应用 (3)使用fleet管理集群 (4)使用etcd实现服务发现:一个分布式的K/V存储 ...

  4. 求n*m网格内矩形的数目

    一个n*m的网格,求这个网格中矩形的数目. 比如以下2*2网格,总共有9个矩形:4个1*1的矩形,4个1*2的矩形,1个2*2的矩形   算法1:动态规划,假设dp[i][j]表示以第 i 行第 j ...

  5. asp.net core 之静态文件目录的操作

    文章前言 之前写了一篇关于模拟登录的文章,自我感觉内容不太丰富,今天的这篇文章,希望在内容上能丰富些.本人缺少写文章的经验,技术上也是新手,但我会努力的,希望大家多多支持小弟. asp.net cor ...

  6. VS2010在运行状态下编辑代码

    在VS2010环境下,当程序处于调试运行状态时,编辑代码会出现下图提示框: 这就给边编辑代码边查看程序运行效果带来不便. 解决方法:在程序没有运行的时候,打开菜单“工具”——>“选项”——> ...

  7. 使用cxf开发webservice应用时抛出异常

    在使用cxf开发webservice应用时,报出了类似下面的错误 JAXB: [javax.xml.bind.UnmarshalException: unexpected element (uri:& ...

  8. 转:HTML5标准与性能之四:asm.js

    HTML5标准与性能之四:asm.js Cong Liu (Intel) 于 星期五, 24/05/2013 - 01:13 提交 之前的几篇文章分别介绍了WebWorkers.Typed Array ...

  9. webClient请求JAVA超时解决方案

    private class MyWebClient: WebClient { protected override WebRequest GetWebRequest(Uri uri) { WebReq ...

  10. Spark源码系列(四)图解作业生命周期

    这一章我们探索了Spark作业的运行过程,但是没把整个过程描绘出来,好,跟着我走吧,let you know! 我们先回顾一下这个图,Driver Program是我们写的那个程序,它的核心是Spar ...