C++ 封装互斥对象
多线程程序中为了防止线程并发造成的竞态,需要经常使用到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++ 封装互斥对象的更多相关文章
- 用C语言封装OC对象(耐心阅读,非常重要)
用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...
- hibernate将本地SQL查询结果封装成对象
hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...
- 互斥对象 Mutex 和MFC中的CMutex
互斥(Mutex)是一种用途非常广泛的内核对象.能够保证多个线程对同一共享资源的互斥访问.同临界区有些类似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共 ...
- Windows多线程同步系列之一-----互斥对象
多线程同步之互斥对象 作者:vpoet mail:vpoet_sir@163.com 对卖票问题进行线程间同步,本文将在上文的基础上,使用互斥对象对线程进行同步. 首先看看windows API ...
- c++多线程编程之互斥对象(锁)的使用之----死锁
一.死锁会在什么情况发生 1.假设有如下代码 mutex; //代表一个全局互斥对象 void A() { mutex.lock(); //这里操作共享数据 B(); //这里调用B方法 mu ...
- XML解析之sax解析案例(二)使用sax解析把 xml文档封装成对象
Demo1类: import java.io.File; import java.util.List; import javax.xml.parsers.SAXParser; import javax ...
- Spring 将请求参数封装成对象
简单描述:最近手里的模块,前后台之间需要传递很多的参数,使用封装的PageData,来获取请求参数的,作微服务迁移的时候,就涉及到需要把参数从pagedata里取出来,一个一个的放到对象的属性中.就很 ...
- c++11の数据竞争和互斥对象
一.数据竞争的产生 在下面例子中: void function_1() { ; i < ; i++) { std::cout << "from function 1:&qu ...
- 通过反射将request中的参数封装到对象中
import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.text.SimpleDateFo ...
随机推荐
- AP6181 正基 WIFI 模块
a. Module size: 12*12mm (pin to pin compatible) Package: Stamp type 44pins AP6181: WiFiAP6210: WiFi/ ...
- AD8275 Driver Amplifiers For Analog-To-Digital Converters
Driver Amplifiers For Analog-To-Digital Converters What amplifiers are used to drive analog-to-digit ...
- SVN仓库删除最近的提交,还原到某日期以前的版本(svn仓库 删除最近几次更改)
由于某日删除了SVN仓库的大量内容,现在突然想恢复,又要保留LOG的连贯性(恢复出来的已删除文件,会是新增,没有之前的历史Log了),所以才有了这需求. Dump版本库的版本(457以后版本不要) - ...
- 【实用技巧】取消Win7开机账户的手动选择
因为前面碰到的一些事情,稍有感慨. 关于win7的一些小技巧都不是什么很有技术含量东西,或者说很浅显.我说一个技巧,也许很多人都知道,也许也早有人说过.但我想说的是我不是在炫耀什么,我只是想分享一些我 ...
- Oracle中Kill session的研究(转 出自eagle)
itpub link: http://www.itpub.net/235873.html 我们知道,在Oracle数据库中,可以通过kill session的方式来终止一个进程,其基本语法结构为: a ...
- atom 安装插件出现 EIO 错误
今天给 atom 安装一个插件autocomplete-python的时候出现错误 npm ERR! Windows_NT 6.1.7600 npm ERR! argv "C:\\Progr ...
- ios中将事件添加到系统日历
- (void)saveEvent:(id)sender { //事件市场 EKEventStore *eventStore = [[EKEventStore alloc] init]; //6.0及 ...
- popupwindow 与 输入法
有时候popupwindow会被输入法覆盖, 有时候popupwindow会被输入法给顶上去. 而且这个问题还跟theme的windowFullscreen属性相关. 不过这些可以都不用管, 根据项目 ...
- C#调用JAVA接口WSSE方式用WebClient方式
C#读取JAVA的WSSE接口的调用代码: 用webclient 方式: /// <summary> /// 调用java cxf ws_security加密的服务wcf客户端对应的加密类 ...
- 通过PowerShell获取TCP响应(类Telnet)
通常情况下,为了检测指定的TCP端口是否存活,我们都是通过telnet指定的端口看是否有响应来确定,然而默认情况下win8以后的系统默认是不安装telnet的.设想一下如果你黑进了一个服务器,上面没装 ...