1.互斥锁简介

互斥锁主要用于互斥,互斥是一种竞争关系,用来保护临界资源一次只被一个线程访问。 
POSIX Pthread提供下面函数用来操作互斥锁。

int pthread_mutex_init(pthread_mutex_t  *mutex,  const  pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//返回:
//pthread_mutex_init总是返回0
//其他mutex函数返回0表示成功,非0的错误码表示失败
#define CHECK(exp) \
if(!exp) \
{ \
fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n",__FILE__, __LINE__); abort();\
}

 由于pthread系列函数返回成功的时候都是0,因此,我们可以写一个宏作为一个轻量级的检查手段,来判断处理错误。

实际使用的时候只需:     CHECK(!pthread_mutex_lock(&mutex));

2.互斥锁的封装

需要考虑以下几个问题:

a.互斥锁的初始化与销毁。 
b.互斥锁的操作:加锁和释放锁。

另外,我们的自己封装的类不应该有赋值和拷贝构造的语义,这一点跟单例模式类似,我们可以使我们的类继承自boost库的noncopyable。

//MutexLock.h

#ifndef __MUTEXLOCK_H__
#define __MUTEXLOCK_H__
#include <iostream>
#include <cstdio>
#include <boost/noncopyable.hpp>
#include <pthread.h>
#include <assert.h> #define CHECK(exp) \
if(!exp) \
{ \
fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n",__FILE__, __LINE__); abort();\
} class MutexLock : public boost::noncopyable
{
friend class Condition;//条件变量友元声明
public:
MutexLock();
~MutexLock();
void lock();
void unlock();
bool isLocking() const
{
return isLocking_;
}
pthread_mutex_t *getMutexPtr()
{
return &mutex_;
}
private:
void restoreMutexStatus()
{
isLocking_=true;
}
pthread_mutex_t mutex_;//互斥锁
bool isLocking_;
};
#endif

  这里完成了MutexLock 类的声明,但是这里还需要一些补充,那就是使用RAII(资源获取即初始化)技术,对MutexLock初始化和析构进行处理:初始化的时候加锁,析构的时候解锁,这就需要我们重新定义一个class MutexLockGuardMutexLock进行操作

class MutexLockGuard:public boost::noncopyable
{
public:
MutexLockGuard(MutexLock &mutex):mutex_(mutex){ mutex_.lock();}//构造时加锁
~MutexLockGuard()//析构时解锁
{
mutex_.unlock();
}
private:
MutexLock &mutex_;//注意这里为什么是引用!!!!
};

下面就要具体实现几个函数了,主要是: 
pthread_mutex_init()pthread_mutex_destroy()pthread_mutex_lock()pthread_mutex_unlock()这四个函数的封装:

#include "MutexLock.h"
MutexLock::MutexLock():isLocking_(false)
{
CHECK(!pthread_mutex_init(&mutex_,NULL));
}
MutexLock::~MutexLock()
{
assert(!isLocking());
CHECK(!pthread_mutex_destroy(&mutex_));
}
void MutexLock::lock()
{
CHECK(!pthread_mutex_lock(&mutex_))//先加锁再修改状态,保证以下赋值操作的原子性。
isLocking_=true;
} void MutexLock::unlock()
{
isLocking_=false;//先修改状态在解锁,保证赋值操作的原子性。
CHECK(!pthread_mutex_unlock(&mutex_));
}

封装以后,我们使用:

MutexLockGurad lock(mutex);//就是  MutexLock对象被另一个对象管理
对临界区进行加锁,而只要我们控制好lock变量的生存期,就能控制临界区,例如:
int count=;
{
MutexLockGurad lock(mutex);
count++;
}//临界区
//...
//离开lock的作用域,lock作为栈上变量,自动释放,调用析构函数,同时释放锁。


 

最新文章

  1. Hibernate项目用Maven创建(转)
  2. iOS 二维数组排序小算法
  3. R中将list类型数据转换成data.frame型
  4. 配置sshd_config中的PermitRootLogin设置root登录或者禁止root登录
  5. Yii系列教程(二):功能简介
  6. react 编写组件 五
  7. webview调用javascript脚本无反应
  8. C# WinForm多线程(二)ThreadPool 与 Timer
  9. sessionstorage,localstorage和cookie之间的区别以及各自的用法
  10. 实现一个竖直的显示表头的表格(vue版本)
  11. hibernate实体对象的三种状态:自由状态,持久状态,游离状态.
  12. 如何成为Android高手
  13. 2018-2019-2 20175306实验一《Java开发环境的熟悉》实验报告
  14. sqlserver 查询表锁死,解除表锁死
  15. rest framework 源码流程
  16. ANTLR#1:描述一个简单计算器
  17. js 下关于json的销毁和添加
  18. Linux(Centos )的网络内核参数优化来提高服务器并发处理能力【转】
  19. 可视化库-Matplotlib-直方图(第四天)
  20. Many-to-many relationships in EF Core 2.0 – Part 3: Hiding as ICollection

热门文章

  1. Mat的迭代器使用
  2. java快排(两种方法)
  3. Mysql--连接查询
  4. &#39;module&#39; object has no attribute &#39;contrib&#39;
  5. .NET 实体转换辅助类
  6. 在GridView控件FooterTemplate内添加记录 Ver3
  7. dubbo心跳机制 (2)
  8. oracle select非group by的字段
  9. uoj#453. 【集训队作业2018】围绕着我们的圆环(线性代数+递推)
  10. 一些意想不到的小bug。