(7)std::mutex/unique_lock/lock_guard

C++11中新增了<mutex>,Mutex互斥量, 它是C++标准程序库中的一个头文件。

std::mutex不支持copy和move操作,最初的std::mutex对象是处于unlocked状态。
Mutex 系列类(四种)
    std::mutex,最基本的 Mutex 类。
    std::recursive_mutex,递归 Mutex 类。
    std::time_mutex,定时 Mutex 类。
    std::recursive_timed_mutex,定时递归 Mutex 类。
Lock 类(两种)
    std::lock_guard,与 Mutex RAII 相关,方便线程对互斥量上锁。
    std::unique_lock,与 Mutex RAII 相关,方便线程对互斥量上锁,但提供了更好的上锁和解锁控制。
其他类型
    std::once_flag
    std::adopt_lock_t
    std::defer_lock_t
    std::try_to_lock_t
1、lock函数:互斥锁被锁定。线程申请该互斥锁,如果未能获得该互斥锁,则调用线程将阻塞(block)在该互斥锁上;
如果成功获得该互诉锁,该线程一直拥有该互斥锁直到调用unlock解锁;
如果该互斥锁已经被当前调用线程锁住,则产生死锁(deadlock)。

2、unlock函数:解锁,释放调用线程对该互斥锁的所有权。

3、try_lock:尝试锁定互斥锁。
如果互斥锁被其他线程占有,则当前调用线程也不会被阻塞,而是由该函数调用返回false;
如果该互斥锁已经被当前调用线程锁住,则会产生死锁。

4、std::call_once,如果多个线程需要同时调用某个函数,call_once 可以保证多个线程对该函数只调用一次。
// std::unique_lock对mutex进行自动加解锁, 比lock_guard更加灵活。
mutex m;
void fun()
{
  // std::try_to_lock 可以避免一些不必要的等待,会判断当前mutex能否被上锁,如果不能被lock,可以先去执行其他代码。
  // 线程没有 m 的所有权,根据块语句的 m 实现自动加解锁。
   std::unique_lock<std::mutex> mlock(m, std::try_to_lock);
   if (mlock.owns_lock() == true) {
      // to do ...
   }
   else {
      // to do other
   }
}
// std::lock_guard对mutex进行自动加解锁。
void fun()
{
   lock_guard<mutex> mlock(m);
}
线程拥有 m 的所有权,实现自动加解锁。
线程读取 m 失败时,则一直等待,直到读取成功。
线程会把 m 一直占有,直到当前线程完成才释放,其它线程才能访问。
posted @ 2018-12-09 19:06  osbreak  阅读(1223)  评论(0)    收藏  举报