• D.5 <mutex>头文件
    • D.5.1 std::mutex类
      • std::mutex 默认构造函数
      • std::mutex 析构函数
      • std::mutex::lock 成员函数
      • std::mutex::try_lock 成员函数
      • std::mutex::unlock 成员函数
    • D.5.2 std::recursive_mutex类
      • std::recursive_mutex 默认构造函数
      • std::recursive_mutex 析构函数
      • std::recursive_mutex::lock 成员函数
      • std::recursive_mutex::try_lock 成员函数
      • std::recursive_mutex::unlock 成员函数
    • D.5.3 std::timed_mutex类
      • std::timed_mutex 默认构造函数
      • std::timed_mutex 析构函数
      • std::timed_mutex::lock 成员函数
      • std::timed_mutex::try_lock 成员函数
      • std::timed_mutex::try_lock_for 成员函数
      • std::timed_mutex::try_lock_until 成员函数
      • std::timed_mutex::unlock 成员函数
    • D.5.4 std::recursive_timed_mutex类
      • std::recursive_timed_mutex 默认构造函数
      • std::recursive_timed_mutex 析构函数
      • std::recursive_timed_mutex::lock 成员函数
      • std::recursive_timed_mutex::try_lock 成员函数
      • std::recursive_timed_mutex::try_lock_for 成员函数
      • std::recursive_timed_mutex::try_lock_until 成员函数
      • std::recursive_timed_mutex::unlock 成员函数
    • D.5.5 std::lock_guard类型模板
      • std::lock_guard 自动上锁的构造函数
      • std::lock_guard 获取锁的构造函数
      • std::lock_guard 析构函数
    • D.5.6 std::unique_lock类型模板
      • std::unique_lock 默认构造函数
      • std::unique_lock 自动上锁的构造函数
      • std::unique_lock 获取锁的构造函数
      • std::unique_lock 递延锁的构造函数
      • std::unique_lock 尝试获取锁的构造函数
      • std::unique_lock 在给定时长内尝试获取锁的构造函数
      • std::unique_lock 在给定时间点内尝试获取锁的构造函数
      • std::unique_lock 移动构造函数
      • std::unique_lock 移动赋值操作
      • std::unique_lock 析构函数
      • std::unique_lock::swap 成员函数
      • std::unique_lock 上非成员函数swap
      • std::unique_lock::lock 成员函数
      • std::unique_lock::try_lock 成员函数
      • std::unique_lock::unlock 成员函数
      • std::unique_lock::try_lock_for 成员函数
      • std::unique_lock::try_lock_until 成员函数
      • std::unique_lock::operator bool成员函数
      • std::unique_lock::owns_lock 成员函数
      • std::unique_lock::mutex 成员函数
      • std::unique_lock::release 成员函数
    • D.5.7 std::lock函数模板
    • D.5.8 std::try_lock函数模板
    • D.5.9 std::once_flag类
      • std::once_flag 默认构造函数
    • D.5.10 std::call_once函数模板

    D.5 <mutex>头文件

    <mutex>头文件提供互斥工具:互斥类型,锁类型和函数,还有确保操作只执行一次的机制。

    头文件内容

    1. namespace std
    2. {
    3. class mutex;
    4. class recursive_mutex;
    5. class timed_mutex;
    6. class recursive_timed_mutex;
    7. struct adopt_lock_t;
    8. struct defer_lock_t;
    9. struct try_to_lock_t;
    10. constexpr adopt_lock_t adopt_lock{};
    11. constexpr defer_lock_t defer_lock{};
    12. constexpr try_to_lock_t try_to_lock{};
    13. template<typename LockableType>
    14. class lock_guard;
    15. template<typename LockableType>
    16. class unique_lock;
    17. template<typename LockableType1,typename... LockableType2>
    18. void lock(LockableType1& m1,LockableType2& m2...);
    19. template<typename LockableType1,typename... LockableType2>
    20. int try_lock(LockableType1& m1,LockableType2& m2...);
    21. struct once_flag;
    22. template<typename Callable,typename... Args>
    23. void call_once(once_flag& flag,Callable func,Args args...);
    24. }

    D.5.1 std::mutex类

    std::mutex类型为线程提供基本的互斥和同步工具,这些工具可以用来保护共享数据。互斥量可以用来保护数据,互斥量上锁必须要调用lok()或try_lock()。当有一个线程获取已经获取了锁,那么其他线程想要在获取锁的时候,会在尝试或取锁的时候失败(调用try_lock())或阻塞(调用lock()),具体酌情而定。当线程完成对共享数据的访问,之后就必须调用unlock()对锁进行释放,并且允许其他线程来访问这个共享数据。

    std::mutex符合Lockable的需求。

    类型定义

    1. class mutex
    2. {
    3. public:
    4. mutex(mutex const&)=delete;
    5. mutex& operator=(mutex const&)=delete;
    6. constexpr mutex() noexcept;
    7. ~mutex();
    8. void lock();
    9. void unlock();
    10. bool try_lock();
    11. };

    std::mutex 默认构造函数

    构造一个std::mutex对象。

    声明

    1. constexpr mutex() noexcept;

    效果

    构造一个std::mutex实例。

    后置条件

    新构造的std::mutex对象是未锁的。

    抛出

    std::mutex 析构函数

    销毁一个std::mutex对象。

    声明

    1. ~mutex();

    先决条件

    *this必须是未锁的。

    效果

    销毁*this。

    抛出

    std::mutex::lock 成员函数

    为当前线程获取std::mutex上的锁。

    声明

    1. void lock();

    先决条件

    *this上必须没有持有一个锁。

    效果

    阻塞当前线程,知道*this获取锁。

    后置条件

    *this被调用线程锁住。

    抛出

    当有错误产生,抛出std::system_error类型异常。

    std::mutex::try_lock 成员函数

    尝试为当前线程获取std::mutex上的锁。

    声明

    1. bool try_lock();

    先决条件

    *this上必须没有持有一个锁。

    效果

    尝试为当前线程*this获取上的锁,失败时当前线程不会被阻塞。

    返回

    当调用线程获取锁时,返回true。

    后置条件

    当*this被调用线程锁住,则返回true。

    抛出

    NOTE 该函数在获取锁时,可能失败(并返回false),即使没有其他线程持有*this上的锁。

    std::mutex::unlock 成员函数

    释放当前线程获取的std::mutex锁。

    声明

    1. void unlock();

    先决条件

    *this上必须持有一个锁。

    效果
    释放当前线程获取到*this上的锁。任意等待获取*this上的线程,会在该函数调用后解除阻塞。

    后置条件

    调用线程不在拥有*this上的锁。

    抛出

    D.5.2 std::recursive_mutex类

    std::recursive_mutex类型为线程提供基本的互斥和同步工具,可以用来保护共享数据。互斥量可以用来保护数据,互斥量上锁必须要调用lok()或try_lock()。当有一个线程获取已经获取了锁,那么其他线程想要在获取锁的时候,会在尝试或取锁的时候失败(调用try_lock())或阻塞(调用lock()),具体酌情而定。当线程完成对共享数据的访问,之后就必须调用unlock()对锁进行释放,并且允许其他线程来访问这个共享数据。

    这个互斥量是可递归的,所以一个线程获取std::recursive_mutex后可以在之后继续使用lock()或try_lock()来增加锁的计数。只有当线程调用unlock释放锁,其他线程才可能用lock()或try_lock()获取锁。

    std::recursive_mutex符合Lockable的需求。

    类型定义

    1. class recursive_mutex
    2. {
    3. public:
    4. recursive_mutex(recursive_mutex const&)=delete;
    5. recursive_mutex& operator=(recursive_mutex const&)=delete;
    6. recursive_mutex() noexcept;
    7. ~recursive_mutex();
    8. void lock();
    9. void unlock();
    10. bool try_lock() noexcept;
    11. };

    std::recursive_mutex 默认构造函数

    构造一个std::recursive_mutex对象。

    声明

    1. recursive_mutex() noexcept;

    效果

    构造一个std::recursive_mutex实例。

    后置条件

    新构造的std::recursive_mutex对象是未锁的。

    抛出

    当无法创建一个新的std::recursive_mutex时,抛出std::system_error异常。

    std::recursive_mutex 析构函数

    销毁一个std::recursive_mutex对象。

    声明

    1. ~recursive_mutex();

    先决条件

    *this必须是未锁的。

    效果

    销毁*this。

    抛出

    std::recursive_mutex::lock 成员函数

    为当前线程获取std::recursive_mutex上的锁。

    声明

    1. void lock();

    效果

    阻塞线程,直到获取*this上的锁。

    先决条件

    调用线程锁住this上的锁。当调用已经持有一个this的锁时,锁的计数会增加1。

    抛出

    当有错误产生,将抛出std::system_error异常。

    std::recursive_mutex::try_lock 成员函数

    尝试为当前线程获取std::recursive_mutex上的锁。

    声明

    1. bool try_lock() noexcept;

    效果

    尝试为当前线程*this获取上的锁,失败时当前线程不会被阻塞。

    返回

    当调用线程获取锁时,返回true;否则,返回false。

    后置条件

    当*this被调用线程锁住,则返回true。

    抛出

    NOTE 该函数在获取锁时,当函数返回true时,*this上对锁的计数会加一。如果当前线程还未获取*this上的锁,那么该函数在获取锁时,可能失败(并返回false),即使没有其他线程持有*this上的锁。

    std::recursive_mutex::unlock 成员函数

    释放当前线程获取的std::recursive_mutex锁。

    声明

    1. void unlock();

    先决条件

    *this上必须持有一个锁。

    效果
    释放当前线程获取到*this上的锁。如果这是*this在当前线程上最后一个锁,那么任意等待获取*this上的线程,会在该函数调用后解除其中一个线程的阻塞。

    后置条件

    *this上锁的计数会在该函数调用后减一。

    抛出

    D.5.3 std::timed_mutex类

    std::timed_mutex类型在std::mutex基本互斥和同步工具的基础上,让锁支持超时。互斥量可以用来保护数据,互斥量上锁必须要调用lok(),try_lock_for(),或try_lock_until()。当有一个线程获取已经获取了锁,那么其他线程想要在获取锁的时候,会在尝试或取锁的时候失败(调用try_lock())或阻塞(调用lock()),或直到想要获取锁可以获取,亦或想要获取的锁超时(调用try_lock_for()或try_lock_until())。在线程调用unlock()对锁进行释放,其他线程才能获取这个锁被获取(不管是调用的哪个函数)。

    std::timed_mutex符合TimedLockable的需求。

    类型定义

    1. class timed_mutex
    2. {
    3. public:
    4. timed_mutex(timed_mutex const&)=delete;
    5. timed_mutex& operator=(timed_mutex const&)=delete;
    6. timed_mutex();
    7. ~timed_mutex();
    8. void lock();
    9. void unlock();
    10. bool try_lock();
    11. template<typename Rep,typename Period>
    12. bool try_lock_for(
    13. std::chrono::duration<Rep,Period> const& relative_time);
    14. template<typename Clock,typename Duration>
    15. bool try_lock_until(
    16. std::chrono::time_point<Clock,Duration> const& absolute_time);
    17. };

    std::timed_mutex 默认构造函数

    构造一个std::timed_mutex对象。

    声明

    1. timed_mutex();

    效果

    构造一个std::timed_mutex实例。

    后置条件

    新构造一个未上锁的std::timed_mutex对象。

    抛出

    当无法创建出新的std::timed_mutex实例时,抛出std::system_error类型异常。

    std::timed_mutex 析构函数

    销毁一个std::timed_mutex对象。

    声明

    1. ~timed_mutex();

    先决条件

    *this必须没有上锁。

    效果

    销毁*this。

    抛出

    std::timed_mutex::lock 成员函数

    为当前线程获取std::timed_mutex上的锁。

    声明

    1. void lock();

    先决条件

    调用线程不能已经持有*this上的锁。

    效果

    阻塞当前线程,直到获取到*this上的锁。

    后置条件

    *this被调用线程锁住。

    抛出

    当有错误产生,抛出std::system_error类型异常。

    std::timed_mutex::try_lock 成员函数

    尝试获取为当前线程获取std::timed_mutex上的锁。

    声明

    1. bool try_lock();

    先决条件

    调用线程不能已经持有*this上的锁。

    效果

    尝试获取*this上的锁,当获取失败时,不阻塞调用线程。

    返回

    当锁被调用线程获取,返回true;反之,返回false。

    后置条件

    当函数返回为true,*this则被当前线程锁住。

    抛出

    NOTE 即使没有线程已获取*this上的锁,函数还是有可能获取不到锁(并返回false)。

    std::timed_mutex::try_lock_for 成员函数

    尝试获取为当前线程获取std::timed_mutex上的锁。

    声明

    1. template<typename Rep,typename Period>
    2. bool try_lock_for(
    3. std::chrono::duration<Rep,Period> const& relative_time);

    先决条件

    调用线程不能已经持有*this上的锁。

    效果

    在指定的relative_time时间内,尝试获取*this上的锁。当relative_time.count()为0或负数,将会立即返回,就像调用try_lock()一样。否则,将会阻塞,直到获取锁或超过给定的relative_time的时间。

    返回

    当锁被调用线程获取,返回true;反之,返回false。

    后置条件

    当函数返回为true,*this则被当前线程锁住。

    抛出

    NOTE 即使没有线程已获取*this上的锁,函数还是有可能获取不到锁(并返回false)。线程阻塞的时长可能会长于给定的时间。逝去的时间可能是由一个稳定时钟所决定。

    std::timed_mutex::try_lock_until 成员函数

    尝试获取为当前线程获取std::timed_mutex上的锁。

    声明

    1. template<typename Clock,typename Duration>
    2. bool try_lock_until(
    3. std::chrono::time_point<Clock,Duration> const& absolute_time);

    先决条件

    调用线程不能已经持有*this上的锁。

    效果

    在指定的absolute_time时间内,尝试获取*this上的锁。当absolute_time<=Clock::now()时,将会立即返回,就像调用try_lock()一样。否则,将会阻塞,直到获取锁或Clock::now()返回的时间等于或超过给定的absolute_time的时间。

    返回

    当锁被调用线程获取,返回true;反之,返回false。

    后置条件

    当函数返回为true,*this则被当前线程锁住。

    抛出

    NOTE 即使没有线程已获取*this上的锁,函数还是有可能获取不到锁(并返回false)。这里不保证调用函数要阻塞多久,只有在函数返回false后,在Clock::now()返回的时间大于或等于absolute_time时,线程才会接触阻塞。

    std::timed_mutex::unlock 成员函数

    将当前线程持有std::timed_mutex对象上的锁进行释放。

    声明

    1. void unlock();

    先决条件

    调用线程已经持有*this上的锁。

    效果

    当前线程释放*this上的锁。任一阻塞等待获取*this上的线程,将被解除阻塞。

    后置条件

    *this未被调用线程上锁。

    抛出

    D.5.4 std::recursive_timed_mutex类

    std::recursive_timed_mutex类型在std::recursive_mutex提供的互斥和同步工具的基础上,让锁支持超时。互斥量可以用来保护数据,互斥量上锁必须要调用lok(),try_lock_for(),或try_lock_until()。当有一个线程获取已经获取了锁,那么其他线程想要在获取锁的时候,会在尝试或取锁的时候失败(调用try_lock())或阻塞(调用lock()),或直到想要获取锁可以获取,亦或想要获取的锁超时(调用try_lock_for()或try_lock_until())。在线程调用unlock()对锁进行释放,其他线程才能获取这个锁被获取(不管是调用的哪个函数)。

    该互斥量是可递归的,所以获取std::recursive_timed_mutex锁的线程,可以多次的对该实例上的锁获取。所有的锁将会在调用相关unlock()操作后,可由其他线程获取该实例上的锁。

    std::recursive_timed_mutex符合TimedLockable的需求。

    类型定义

    1. class recursive_timed_mutex
    2. {
    3. public:
    4. recursive_timed_mutex(recursive_timed_mutex const&)=delete;
    5. recursive_timed_mutex& operator=(recursive_timed_mutex const&)=delete;
    6. recursive_timed_mutex();
    7. ~recursive_timed_mutex();
    8. void lock();
    9. void unlock();
    10. bool try_lock() noexcept;
    11. template<typename Rep,typename Period>
    12. bool try_lock_for(
    13. std::chrono::duration<Rep,Period> const& relative_time);
    14. template<typename Clock,typename Duration>
    15. bool try_lock_until(
    16. std::chrono::time_point<Clock,Duration> const& absolute_time);
    17. };

    std::recursive_timed_mutex 默认构造函数

    构造一个std::recursive_timed_mutex对象。

    声明

    1. recursive_timed_mutex();

    效果

    构造一个std::recursive_timed_mutex实例。

    后置条件

    新构造的std::recursive_timed_mutex实例是没有上锁的。

    抛出

    当无法创建一个std::recursive_timed_mutex实例时,抛出std::system_error类异常。

    std::recursive_timed_mutex 析构函数

    析构一个std::recursive_timed_mutex对象。

    声明

    1. ~recursive_timed_mutex();

    先决条件

    *this不能上锁。

    效果

    销毁*this。

    抛出

    std::recursive_timed_mutex::lock 成员函数

    为当前线程获取std::recursive_timed_mutex对象上的锁。

    声明

    1. void lock();

    先决条件

    *this上的锁不能被线程调用。

    效果

    阻塞当前线程,直到获取*this上的锁。

    后置条件

    *this被调用线程锁住。当调用线程已经获取*this上的锁,那么锁的计数会再增加1。

    抛出

    当错误出现时,抛出std::system_error类型异常。

    std::recursive_timed_mutex::try_lock 成员函数

    尝试为当前线程获取std::recursive_timed_mutex对象上的锁。

    声明

    1. bool try_lock() noexcept;

    效果

    尝试获取*this上的锁,当获取失败时,直接不阻塞线程。

    返回

    当调用线程获取了锁,返回true,否则返回false。

    后置条件

    当函数返回true,*this会被调用线程锁住。

    抛出

    NOTE 该函数在获取锁时,当函数返回true时,*this上对锁的计数会加一。如果当前线程还未获取*this上的锁,那么该函数在获取锁时,可能失败(并返回false),即使没有其他线程持有*this上的锁。

    std::recursive_timed_mutex::try_lock_for 成员函数

    尝试为当前线程获取std::recursive_timed_mutex对象上的锁。

    声明

    1. template<typename Rep,typename Period>
    2. bool try_lock_for(
    3. std::chrono::duration<Rep,Period> const& relative_time);

    效果

    在指定时间relative_time内,尝试为调用线程获取*this上的锁。当relative_time.count()为0或负数时,将会立即返回,就像调用try_lock()一样。否则,调用会阻塞,直到获取相应的锁,或超出了relative_time时限时,调用线程解除阻塞。

    返回

    当调用线程获取了锁,返回true,否则返回false。

    后置条件

    当函数返回true,*this会被调用线程锁住。

    抛出

    NOTE 该函数在获取锁时,当函数返回true时,*this上对锁的计数会加一。如果当前线程还未获取*this上的锁,那么该函数在获取锁时,可能失败(并返回false),即使没有其他线程持有*this上的锁。等待时间可能要比指定的时间长很多。逝去的时间可能由一个稳定时钟来计算。

    std::recursive_timed_mutex::try_lock_until 成员函数

    尝试为当前线程获取std::recursive_timed_mutex对象上的锁。

    声明

    1. template<typename Clock,typename Duration>
    2. bool try_lock_until(
    3. std::chrono::time_point<Clock,Duration> const& absolute_time);

    效果

    在指定时间absolute_time内,尝试为调用线程获取*this上的锁。当absolute_time<=Clock::now()时,将会立即返回,就像调用try_lock()一样。否则,调用会阻塞,直到获取相应的锁,或Clock::now()返回的时间大于或等于absolute_time时,调用线程解除阻塞。

    返回

    当调用线程获取了锁,返回true,否则返回false。

    后置条件

    当函数返回true,*this会被调用线程锁住。

    抛出

    NOTE 该函数在获取锁时,当函数返回true时,*this上对锁的计数会加一。如果当前线程还未获取*this上的锁,那么该函数在获取锁时,可能失败(并返回false),即使没有其他线程持有*this上的锁。这里阻塞的时间并不确定,只有当函数返回false,然后Clock::now()返回的时间大于或等于absolute_time时,调用线程将会解除阻塞。

    std::recursive_timed_mutex::unlock 成员函数

    释放当前线程获取到的std::recursive_timed_mutex上的锁。

    声明

    1. void unlock();

    效果

    当前线程释放*this上的锁。当*this上最后一个锁被释放后,任何等待获取*this上的锁将会解除阻塞,不过只能解除其中一个线程的阻塞。

    后置条件

    调用线程*this上锁的计数减一。

    抛出

    D.5.5 std::lock_guard类型模板

    std::lock_guard类型模板为基础锁包装所有权。所要上锁的互斥量类型,由模板参数Mutex来决定,并且必须符合Lockable的需求。指定的互斥量在构造函数中上锁,在析构函数中解锁。这就为互斥量锁部分代码提供了一个简单的方式;当程序运行完成时,阻塞解除,互斥量解锁(无论是执行到最后,还是通过控制流语句break或return,亦或是抛出异常)。

    std::lock_guard是不可MoveConstructible(移动构造), CopyConstructible(拷贝构造)和CopyAssignable(拷贝赋值)。

    类型定义

    1. template <class Mutex>
    2. class lock_guard
    3. {
    4. public:
    5. typedef Mutex mutex_type;
    6. explicit lock_guard(mutex_type& m);
    7. lock_guard(mutex_type& m, adopt_lock_t);
    8. ~lock_guard();
    9. lock_guard(lock_guard const& ) = delete;
    10. lock_guard& operator=(lock_guard const& ) = delete;
    11. };

    std::lock_guard 自动上锁的构造函数

    使用互斥量构造一个std::lock_guard实例。

    声明

    1. explicit lock_guard(mutex_type& m);

    效果

    通过引用提供的互斥量,构造一个新的std::lock_guard实例,并调用m.lock()。

    抛出

    m.lock()抛出的任何异常。

    后置条件

    *this拥有m上的锁。

    std::lock_guard 获取锁的构造函数

    使用已提供互斥量上的锁,构造一个std::lock_guard实例。

    声明

    1. lock_guard(mutex_type& m,std::adopt_lock_t);

    先决条件

    调用线程必须拥有m上的锁。

    效果

    调用线程通过引用提供的互斥量,以及获取m上锁的所有权,来构造一个新的std::lock_guard实例。

    抛出

    后置条件

    *this拥有m上的锁。

    std::lock_guard 析构函数

    销毁一个std::lock_guard实例,并且解锁相关互斥量。

    声明

    1. ~lock_guard();

    效果

    当*this被创建后,调用m.unlock()。

    抛出

    D.5.6 std::unique_lock类型模板

    std::unique_lock类型模板相较std::loc_guard提供了更通用的所有权包装器。上锁的互斥量可由模板参数Mutex提供,这个类型必须满足BasicLockable的需求。虽然,通常情况下,制定的互斥量会在构造的时候上锁,析构的时候解锁,但是附加的构造函数和成员函数提供灵活的功能。互斥量上锁,意味着对操作同一段代码的线程进行阻塞;当互斥量解锁,就意味着阻塞解除(不论是裕兴到最后,还是使用控制语句break和return,亦或是抛出异常)。std::condition_variable的邓丹函数是需要std::unique_lock<std::mutex>实例的,并且所有std::unique_lock实例都适用于std::conditin_variable_any等待函数的Lockable参数。

    当提供的Mutex类型符合Lockable的需求,那么std::unique_lock<Mutex>也是符合Lockable的需求。此外,如果提供的Mutex类型符合TimedLockable的需求,那么std::unique_lock<Mutex>也符合TimedLockable的需求。

    std::unique_lock实例是MoveConstructible(移动构造)和MoveAssignable(移动赋值),但是不能CopyConstructible(拷贝构造)和CopyAssignable(拷贝赋值)。

    类型定义

    1. template <class Mutex>
    2. class unique_lock
    3. {
    4. public:
    5. typedef Mutex mutex_type;
    6. unique_lock() noexcept;
    7. explicit unique_lock(mutex_type& m);
    8. unique_lock(mutex_type& m, adopt_lock_t);
    9. unique_lock(mutex_type& m, defer_lock_t) noexcept;
    10. unique_lock(mutex_type& m, try_to_lock_t);
    11. template<typename Clock,typename Duration>
    12. unique_lock(
    13. mutex_type& m,
    14. std::chrono::time_point<Clock,Duration> const& absolute_time);
    15. template<typename Rep,typename Period>
    16. unique_lock(
    17. mutex_type& m,
    18. std::chrono::duration<Rep,Period> const& relative_time);
    19. ~unique_lock();
    20. unique_lock(unique_lock const& ) = delete;
    21. unique_lock& operator=(unique_lock const& ) = delete;
    22. unique_lock(unique_lock&& );
    23. unique_lock& operator=(unique_lock&& );
    24. void swap(unique_lock& other) noexcept;
    25. void lock();
    26. bool try_lock();
    27. template<typename Rep, typename Period>
    28. bool try_lock_for(
    29. std::chrono::duration<Rep,Period> const& relative_time);
    30. template<typename Clock, typename Duration>
    31. bool try_lock_until(
    32. std::chrono::time_point<Clock,Duration> const& absolute_time);
    33. void unlock();
    34. explicit operator bool() const noexcept;
    35. bool owns_lock() const noexcept;
    36. Mutex* mutex() const noexcept;
    37. Mutex* release() noexcept;
    38. };

    std::unique_lock 默认构造函数

    不使用相关互斥量,构造一个std::unique_lock实例。

    声明

    1. unique_lock() noexcept;

    效果

    构造一个std::unique_lock实例,这个新构造的实例没有相关互斥量。

    后置条件

    this->mutex()==NULL, this->owns_lock()==false.

    std::unique_lock 自动上锁的构造函数

    使用相关互斥量,构造一个std::unique_lock实例。

    声明

    1. explicit unique_lock(mutex_type& m);

    效果

    通过提供的互斥量,构造一个std::unique_lock实例,且调用m.lock()。

    抛出

    m.lock()抛出的任何异常。

    后置条件

    this->owns_lock()==true, this->mutex()==&m.

    std::unique_lock 获取锁的构造函数

    使用相关互斥量和持有的锁,构造一个std::unique_lock实例。

    声明

    1. unique_lock(mutex_type& m,std::adopt_lock_t);

    先决条件

    调用线程必须持有m上的锁。

    效果

    通过提供的互斥量和已经拥有m上的锁,构造一个std::unique_lock实例。

    抛出

    后置条件

    this->owns_lock()==true, this->mutex()==&m.

    std::unique_lock 递延锁的构造函数

    使用相关互斥量和非持有的锁,构造一个std::unique_lock实例。

    声明

    1. unique_lock(mutex_type& m,std::defer_lock_t) noexcept;

    效果

    构造的std::unique_lock实例引用了提供的互斥量。

    抛出

    后置条件

    this->owns_lock()==false, this->mutex()==&m.

    std::unique_lock 尝试获取锁的构造函数

    使用提供的互斥量,并尝试从互斥量上获取锁,从而构造一个std::unique_lock实例。

    声明

    1. unique_lock(mutex_type& m,std::try_to_lock_t);

    先决条件

    使std::unique_lock实例化的Mutex类型,必须符合Loackable的需求。

    效果

    构造的std::unique_lock实例引用了提供的互斥量,且调用m.try_lock()。

    抛出

    后置条件

    this->owns_lock()将返回m.try_lock()的结果,且this->mutex()==&m。

    std::unique_lock 在给定时长内尝试获取锁的构造函数

    使用提供的互斥量,并尝试从互斥量上获取锁,从而构造一个std::unique_lock实例。

    声明

    1. template<typename Rep,typename Period>
    2. unique_lock(
    3. mutex_type& m,
    4. std::chrono::duration<Rep,Period> const& relative_time);

    先决条件

    使std::unique_lock实例化的Mutex类型,必须符合TimedLockable的需求。

    效果

    构造的std::unique_lock实例引用了提供的互斥量,且调用m.try_lock_for(relative_time)。

    抛出

    后置条件

    this->owns_lock()将返回m.try_lock_for()的结果,且this->mutex()==&m。

    std::unique_lock 在给定时间点内尝试获取锁的构造函数

    使用提供的互斥量,并尝试从互斥量上获取锁,从而构造一个std::unique_lock实例。

    声明

    1. template<typename Clock,typename Duration>
    2. unique_lock(
    3. mutex_type& m,
    4. std::chrono::time_point<Clock,Duration> const& absolute_time);

    先决条件

    使std::unique_lock实例化的Mutex类型,必须符合TimedLockable的需求。

    效果

    构造的std::unique_lock实例引用了提供的互斥量,且调用m.try_lock_until(absolute_time)。

    抛出

    后置条件

    this->owns_lock()将返回m.try_lock_until()的结果,且this->mutex()==&m。

    std::unique_lock 移动构造函数

    将一个已经构造std::unique_lock实例的所有权,转移到新的std::unique_lock实例上去。

    声明

    1. unique_lock(unique_lock&& other) noexcept;

    先决条件

    使std::unique_lock实例化的Mutex类型,必须符合TimedLockable的需求。

    效果

    构造的std::unique_lock实例。当other在函数调用的时候拥有互斥量上的锁,那么该锁的所有权将被转移到新构建的std::unique_lock对象当中去。

    后置条件

    对于新构建的std::unique_lock对象x,x.mutex等价与在构造函数调用前的other.mutex(),并且x.owns_lock()等价于函数调用前的other.owns_lock()。在调用函数后,other.mutex()==NULL,other.owns_lock()=false。

    抛出

    NOTE std::unique_lock对象是不可CopyConstructible(拷贝构造),所以这里没有拷贝构造函数,只有移动构造函数。

    std::unique_lock 移动赋值操作

    将一个已经构造std::unique_lock实例的所有权,转移到新的std::unique_lock实例上去。

    声明

    1. unique_lock& operator=(unique_lock&& other) noexcept;

    效果

    当this->owns_lock()返回true时,调用this->unlock()。如果other拥有mutex上的锁,那么这个所将归*this所有。

    后置条件

    this->mutex()等于在为进行赋值前的other.mutex(),并且this->owns_lock()的值与进行赋值操作前的other.owns_lock()相等。other.mutex()==NULL, other.owns_lock()==false。

    抛出

    NOTE std::unique_lock对象是不可CopyAssignable(拷贝赋值),所以这里没有拷贝赋值函数,只有移动赋值函数。

    std::unique_lock 析构函数

    销毁一个std::unique_lock实例,如果该实例拥有锁,那么会将相关互斥量进行解锁。

    声明

    1. ~unique_lock();

    效果

    当this->owns_lock()返回true时,调用this->mutex()->unlock()。

    抛出

    std::unique_lock::swap 成员函数

    交换std::unique_lock实例中相关的所有权。

    声明

    1. void swap(unique_lock& other) noexcept;

    效果

    如果other在调用该函数前拥有互斥量上的锁,那么这个锁将归*this所有。如果*this在调用哎函数前拥有互斥量上的锁,那么这个锁将归other所有。

    抛出

    std::unique_lock 上非成员函数swap

    交换std::unique_lock实例中相关的所有权。

    声明

    1. void swap(unique_lock& lhs,unique_lock& rhs) noexcept;

    效果

    lhs.swap(rhs)

    抛出

    std::unique_lock::lock 成员函数

    获取与*this相关互斥量上的锁。

    声明

    1. void lock();

    先决条件

    this->mutex()!=NULL, this->owns_lock()==false.

    效果

    调用this->mutex()->lock()。

    抛出

    抛出任何this->mutex()->lock()所抛出的异常。当this->mutex()==NULL,抛出std::sytem_error类型异常,错误码为std::errc::operation_not_permitted。当this->owns_lock()==true时,抛出std::system_error,错误码为std::errc::resource_deadlock_would_occur

    后置条件

    this->owns_lock()==true。

    std::unique_lock::try_lock 成员函数

    尝试获取与*this相关互斥量上的锁。

    声明

    1. bool try_lock();

    先决条件

    std::unique_lock实例化说是用的Mutex类型,必须满足Lockable需求。this->mutex()!=NULL, this->owns_lock()==false。

    效果

    调用this->mutex()->try_lock()。

    抛出

    抛出任何this->mutex()->try_lock()所抛出的异常。当this->mutex()==NULL,抛出std::sytem_error类型异常,错误码为std::errc::operation_not_permitted。当this->owns_lock()==true时,抛出std::system_error,错误码为std::errc::resource_deadlock_would_occur

    后置条件

    当函数返回true时,this->ows_lock()==true,否则this->owns_lock()==false。

    std::unique_lock::unlock 成员函数

    释放与*this相关互斥量上的锁。

    声明

    1. void unlock();

    先决条件

    this->mutex()!=NULL, this->owns_lock()==true。

    抛出

    抛出任何this->mutex()->unlock()所抛出的异常。当this->owns_lock()==false时,抛出std::system_error,错误码为std::errc::operation_not_permitted

    后置条件

    this->owns_lock()==false。

    std::unique_lock::try_lock_for 成员函数

    在指定时间内尝试获取与*this相关互斥量上的锁。

    声明

    1. template<typename Rep, typename Period>
    2. bool try_lock_for(
    3. std::chrono::duration<Rep,Period> const& relative_time);

    先决条件

    std::unique_lock实例化说是用的Mutex类型,必须满足TimedLockable需求。this->mutex()!=NULL, this->owns_lock()==false。

    效果

    调用this->mutex()->try_lock_for(relative_time)。

    返回

    当this->mutex()->try_lock_for()返回true,返回true,否则返回false。

    抛出

    抛出任何this->mutex()->try_lock_for()所抛出的异常。当this->mutex()==NULL,抛出std::sytem_error类型异常,错误码为std::errc::operation_not_permitted。当this->owns_lock()==true时,抛出std::system_error,错误码为std::errc::resource_deadlock_would_occur

    后置条件

    当函数返回true时,this->ows_lock()==true,否则this->owns_lock()==false。

    std::unique_lock::try_lock_until 成员函数

    在指定时间点尝试获取与*this相关互斥量上的锁。

    声明

    1. template<typename Clock, typename Duration>
    2. bool try_lock_until(
    3. std::chrono::time_point<Clock,Duration> const& absolute_time);

    先决条件

    std::unique_lock实例化说是用的Mutex类型,必须满足TimedLockable需求。this->mutex()!=NULL, this->owns_lock()==false。

    效果

    调用this->mutex()->try_lock_until(absolute_time)。

    返回

    当this->mutex()->try_lock_for()返回true,返回true,否则返回false。

    抛出

    抛出任何this->mutex()->try_lock_for()所抛出的异常。当this->mutex()==NULL,抛出std::sytem_error类型异常,错误码为std::errc::operation_not_permitted。当this->owns_lock()==true时,抛出std::system_error,错误码为std::errc::resource_deadlock_would_occur

    后置条件

    当函数返回true时,this->ows_lock()==true,否则this->owns_lock()==false。

    std::unique_lock::operator bool成员函数

    检查*this是否拥有一个互斥量上的锁。

    声明

    1. explicit operator bool() const noexcept;

    返回

    this->owns_lock()

    抛出

    NOTE 这是一个explicit转换操作,所以当这样的操作在上下文中只能被隐式的调用,所返回的结果需要被当做一个布尔量进行使用,而非仅仅作为整型数0或1。

    std::unique_lock::owns_lock 成员函数

    检查*this是否拥有一个互斥量上的锁。

    声明

    1. bool owns_lock() const noexcept;

    返回

    当*this持有一个互斥量的锁,返回true;否则,返回false。

    抛出

    std::unique_lock::mutex 成员函数

    当*this具有相关互斥量时,返回这个互斥量

    声明

    1. mutex_type* mutex() const noexcept;

    返回

    当*this有相关互斥量,则返回该互斥量;否则,返回NULL。

    抛出

    std::unique_lock::release 成员函数

    当*this具有相关互斥量时,返回这个互斥量,并将这个互斥量进行释放。

    声明

    1. mutex_type* release() noexcept;

    效果

    将*this与相关的互斥量之间的关系解除,同时解除所有持有锁的所有权。

    返回

    返回与*this相关的互斥量指针,如果没有相关的互斥量,则返回NULL。

    后置条件

    this->mutex()==NULL, this->owns_lock()==false。

    抛出

    NOTE 如果this->owns_lock()在调用该函数前返回true,那么调用者则有责任里解除互斥量上的锁。

    D.5.7 std::lock函数模板

    std::lock函数模板提供同时锁住多个互斥量的功能,且不会有因改变锁的一致性而导致的死锁。

    声明

    1. template<typename LockableType1,typename... LockableType2>
    2. void lock(LockableType1& m1,LockableType2& m2...);

    先决条件

    提供的可锁对象LockableType1, LockableType2…,需要满足Lockable的需求。

    效果

    使用未指定顺序调用lock(),try_lock()获取每个可锁对象(m1, m2…)上的锁,还有unlock()成员来避免这个类型陷入死锁。

    后置条件

    当前线程拥有提供的所有可锁对象上的锁。

    抛出

    任何lock(), try_lock()和unlock()抛出的异常。

    NOTE 如果一个异常由std::lock所传播开来,当可锁对象上有锁被lock()或try_lock()获取,那么unlock()会使用在这些可锁对象上。

    D.5.8 std::try_lock函数模板

    std::try_lock函数模板允许尝试获取一组可锁对象上的锁,所以要不全部获取,要不一个都不获取。

    声明

    1. template<typename LockableType1,typename... LockableType2>
    2. int try_lock(LockableType1& m1,LockableType2& m2...);

    先决条件

    提供的可锁对象LockableType1, LockableType2…,需要满足Lockable的需求。

    效果

    使用try_lock()尝试从提供的可锁对象m1,m2…上逐个获取锁。当锁在之前获取过,但被当前线程使用unlock()对相关可锁对象进行了释放后,try_lock()会返回false或抛出一个异常。

    返回

    当所有锁都已获取(每个互斥量调用try_lock()返回true),则返回-1,否则返回以0为基数的数字,其值为调用try_lock()返回false的个数。

    后置条件

    当函数返回-1,当前线程获取从每个可锁对象上都获取一个锁。否则,通过该调用获取的任何锁都将被释放。

    抛出

    try_lock()抛出的任何异常。

    NOTE 如果一个异常由std::try_lock所传播开来,则通过try_lock()获取锁对象,将会调用unlock()解除对锁的持有。

    D.5.9 std::once_flag类

    std::once_flagstd::call_once一起使用,为了保证某特定函数只执行一次(即使有多个线程在并发的调用该函数)。

    std::once_flag实例是不能CopyConstructible(拷贝构造),CopyAssignable(拷贝赋值),MoveConstructible(移动构造),以及MoveAssignable(移动赋值)。

    类型定义

    1. struct once_flag
    2. {
    3. constexpr once_flag() noexcept;
    4. once_flag(once_flag const& ) = delete;
    5. once_flag& operator=(once_flag const& ) = delete;
    6. };

    std::once_flag 默认构造函数

    std::once_flag默认构造函数创建了一个新的std::once_flag实例(并包含一个状态,这个状态表示相关函数没有被调用)。

    声明

    1. constexpr once_flag() noexcept;

    效果

    std::once_flag默认构造函数创建了一个新的std::once_flag实例(并包含一个状态,这个状态表示相关函数没有被调用)。因为这是一个constexpr构造函数,在构造的静态初始部分,实例是静态存储的,这样就避免了条件竞争和初始化顺序的问题。

    D.5.10 std::call_once函数模板

    std::call_oncestd::once_flag一起使用,为了保证某特定函数只执行一次(即使有多个线程在并发的调用该函数)。

    声明

    1. template<typename Callable,typename... Args>
    2. void call_once(std::once_flag& flag,Callable func,Args args...);

    先决条件

    表达式INVOKE(func,args)提供的func和args必须是合法的。Callable和每个Args的成员都是可MoveConstructible(移动构造)。

    效果

    在同一个std::once_flag对象上调用std::call_once是串行的。如果之前没有在同一个std::once_flag对象上调用过std::call_once,参数func(或副本)被调用,就像INVOKE(func, args),并且只有可调用的func不抛出任何异常时,调用std::call_once才是有效的。当有异常抛出,异常会被调用函数进行传播。如果之前在std::once_flag上的std::call_once是有效的,那么再次调用std::call_once将不会在调用func。

    同步

    std::once_flag上完成对std::call_once的调用的先决条件是,后续所有对std::call_once调用都在同一std::once_flag对象。

    抛出

    当效果没有达到,或任何异常由调用func而传播,则抛出std::system_error