多线程编程 -- MutexLock

互斥量Mutex

互斥量本质上是一把锁,在访问共享资源钱对互斥量进行加锁,访问完成之后释放互斥量的锁。
pthread_mutex_t , 使用之前,必须首先对初始化

对互斥量进行加锁,调用pthread_mutex_lock
如果互斥量已经上锁,则线程将阻塞知道互斥量被解锁

如果不希望被阻塞,它可以使用pthread_mutex_trylock 尝试对互斥量进行加锁。如果互斥量处于未锁住状态, 那么pthread_mutex_trylock 将锁住互斥量,不会出现阻塞并返回0, 否则pthread_mutex_trylock就会失败,不会锁住互斥量,而返回EBUSY 。
下面来实现一个cpp 版本的Mutex

首先写一个类NoCopy,字面意思就是让类不能复制,具体的就是不能通过构造函数和赋值函数来构造对象。要达到这个目的,只需要自定义类型从这个类派生即可。原理就是把拷贝构造函数和赋值函数屏蔽掉,叫编译器编译不过。

nocopy.h

#ifndef COMMON_BASE_NOCOPY_H_
#define COMMON_BASE_NOCOPY_H_

#ifndef NOCOPY_CLASS
#define NOCOPY_CLASS(Class) \
 private: \
  Class(const Class&) = delete; \
  Class& operator=(const Class&) = delete
#endif

namespace common {
class Uncopyable {
  // private by default
  NOCOPY_CLASS(Uncopyable);
 public:
  Uncopyable() {}
  ~Uncopyable() {}
};
}  // namespace common
typedef common::Uncopyable Uncopyable;
#endif  // COMMON_BASE_NOCOPY_H_

这里使用宏定义NOCOPY 把拷贝构造函数和赋值函数屏蔽掉。

下面是一个cpp 版本的Mutex
mutex.h

class MutexLock {
  NOCOPY_CLASS(MutexLock);
 public:
  MutexLock()
      :status_(true) {
    if (pthread_mutex_init(&lock_, 0) != 0) {
      status_ = false; // 初始化失败
    }
  }

  virtual ~MutexLock() {
    if (status_ == true) {
      pthread_mutex_destroy(&lock_);
    }
  }

  void Lock() {
    if (status_ == true) {
      pthread_mutex_lock(&lock_);
      //assert(IsLocked());
    }
  }

  int TryLock() {
    if (status_ == true) {
      return pthread_mutex_trylock(&lock_);
    }
    return -1;
  }

  void Unlock() {
    //assert(IsLocked());
    if (status_ == true) {
      pthread_mutex_unlock(&lock_);  
    }
}

  bool IsLocked() const {
    return lock_.__data.__lock > 0;  
  }

 private:
  pthread_mutex_t lock_;
  bool status_;
};

注意:
通过成员函数Lock()进行上锁, Unlock() 进行解锁。不过并不推荐实践中直接去调用成员函数,因为调用成员函数就意味着,必须记住在每个函数出口都要去调用unlock(),也包括异常的情况。这是十分蛋疼的一件事。推荐使用 C++标准的RAII 来实现一个lock_guard 模版类,这个类在构造的时候提供已锁的互斥量,并且在析构的时候进行解锁,从而保证了一个已锁的互斥量总是会被正确地解锁。

下面给出lock_guard 的模版类

template <typename LockType>
class LockGuard {
  NOCOPY_CLASS(LockGuard);
 public:
  LockGuard(LockType* lock): lock_(lock) {
    lock_->Lock();
  }
  ~LockGuard() {
    lock_->Unlock();
  }
 private:
  LockType* lock_;
};
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值