Bootstrap

C++多线程:lock

简介:

本篇文章是对C++多线程中使用到的lock的管理方法进行简单的记录。

RAII机制:

RAII,全称为Resource Acquisition Is Initialization,汉语是“资源获取即初始化”。简单说来就是,在资源获取的时候将其封装在某类的object中,利用"栈资源会在相应object的生命周期结束时自动销毁"来自动释放资源,即,构造函数创建时初始化获取资源,并将资源释放写在析构函数中。所以这个RAII其实就是和智能指针的实现是类似的。

C++中锁管理方法:

  • std::lock_guard(C++11)
  • std::unique_lock(C++11)
  • std::share_lock(C++14)
  • std::scoped_lock(C++17)

lock_gurd:

namespace std {
  template<class Mutex>
  class lock_guard {
  public:
    using mutex_type = Mutex;
 
    explicit lock_guard(mutex_type& m);
    lock_guard(mutex_type& m, adopt_lock_t);
    ~lock_guard();
 
    lock_guard(const lock_guard&) = delete;
    lock_guard& operator=(const lock_guard&) = delete;
 
  private:
    mutex_type& pm;             // 仅用于阐释
  };
}

unique_lock

namespace std {
  template<class Mutex>
  class unique_lock {
  public:
    using mutex_type = Mutex;
 
    // 构造/复制/销毁
    unique_lock() noexcept;
    explicit unique_lock(mutex_type& m);
    unique_lock(mutex_type& m, defer_lock_t) noexcept;
    unique_lock(mutex_type& m, try_to_lock_t);
    unique_lock(mutex_type& m, adopt_lock_t);
    template<class Clock, class Duration>
      unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
    template<class Rep, class Period>
      unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
    ~unique_lock();
 
    unique_lock(const unique_lock&) = delete;
    unique_lock& operator=(const unique_lock&) = delete;
 
    unique_lock(unique_lock&& u) noexcept;
    unique_lock& operator=(unique_lock&& u);
 
    // 锁定
    void lock();
    bool try_lock();
 
    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
 
    void unlock();
 
    // 修改器
    void swap(unique_lock& u) noexcept;
    mutex_type* release() noexcept;
 
    // 观察器
    bool owns_lock() const noexcept;
    explicit operator bool () const noexcept;
    mutex_type* mutex() const noexcept;
 
  private:
    mutex_type* pm;             // 仅用于阐释
    bool owns;                  // 仅用于阐释
  };
 
  template<class Mutex>
    void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
}

Shared_lock

namespace std {
  template<class Mutex>
  class shared_lock {
  public:
    using mutex_type = Mutex;
 
    // 构造/复制/析构
    shared_lock() noexcept;
    explicit shared_lock(mutex_type& m);        // 阻塞
    shared_lock(mutex_type& m, defer_lock_t) noexcept;
    shared_lock(mutex_type& m, try_to_lock_t);
    shared_lock(mutex_type& m, adopt_lock_t);
    template<class Clock, class Duration>
      shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
    template<class Rep, class Period>
      shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
    ~shared_lock();
 
    shared_lock(const shared_lock&) = delete;
    shared_lock& operator=(const shared_lock&) = delete;
 
    shared_lock(shared_lock&& u) noexcept;
    shared_lock& operator=(shared_lock&& u) noexcept;
 
    // 锁定
    void lock();                                // 阻塞
    bool try_lock();
    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();
 
    // 修改器
    void swap(shared_lock& u) noexcept;
    mutex_type* release() noexcept;
 
    // 观察器
    bool owns_lock() const noexcept;
    explicit operator bool () const noexcept;
    mutex_type* mutex() const noexcept;
 
  private:
    mutex_type* pm;                             // 仅用于阐释
    bool owns;                                  // 仅用于阐释
  };
 
  template<class Mutex>
    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}

Scpoe_lock

namespace std {
  template<class... MutexTypes>
  class scoped_lock {
  public:
    using mutex_type = Mutex;   // 若 MutexTypes... 仅由单个类型 Mutex 组成
 
    explicit scoped_lock(MutexTypes&... m);
    explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
    ~scoped_lock();
 
    scoped_lock(const scoped_lock&) = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;
 
  private:
    tuple<MutexTypes&...> pm;   // 仅用于阐释
  };
}

总结:

写篇文章主要是为了记录一下四种锁管理机制的源码便于以后复习。如果你想要了解更多的细节可以访问(std::timed_mutex::try_lock_for - C++中文 - API参考文档 (apiref.com)).

;