一. 互斥量
(一)Mutex系列类
1. std::mutex:独占的互斥量,不能递归使用。
2. std::recursive_mutex:递归互斥量。允许同一线程多次获得该互斥锁,可以用来解决同一线程需要多次获取互斥量时死锁的问题。
3. std::time_mutex和std::recursive_time_mutex:带超时的互斥量。前者是超时的独占锁,后者为超时的递归锁。主要用于获取锁时增加超时等待功能,因为有时不知道获取锁需要多久,为了不至于一直等待下去,就设置一个等待超时时间。比std::mutex多了两个超时获取锁的接口:try_lock_for和try_lock_until
//1. 独占互斥锁,不能递归使用 class mutex { public: //std::mutex不支持copy和move操作。 mutex(const mutex&) = delete; mutex& operator=(const mutex&) = delete; constexpr mutex() noexcept; //构造函数:新的对象是未锁的 ~mutex(); void lock(); //上锁 void unlock(); //解锁 bool try_lock(); //尝试上锁。成功,返回true。失败时返回false,但不阻塞。会有三种情况 //(1)如果当前互斥量没被其他线程占有,则锁住互斥量,直到该线程调用unlock //(2)如果当前互斥量被其他线程占用,则调用线程返回false,且不会被阻塞 //(3)如果互斥量己被当前线程锁住,则会产生死锁 }; //2. 递归互斥锁可以被同一个线程多次加锁(增加锁计数),以获得对互斥锁对象的多层所有权。 //可以用来解决同一线程需要多次获取互斥量时死锁的问题 class recursive_mutex { public : recursive_mutex(const recursive_mutex&) = delete; recursive_mutex& operator=(const recursive_mutex&) = delete; recursive_mutex() noexcept; ~recursive_mutex(); void lock(); void unlock(); //释放互斥量时需要调用与该锁层次深度相同次数的unlock(),即lock()次数和unlock()次数相同 bool try_lock() noexcept; }; //3. 带超时的互斥锁,不能递归使用 class timed_mutex { public : timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; timed_mutex(); ~timed_mutex(); void lock(); void unlock(); bool try_lock(); //在指定的relative_time时间内,尝试获取*this上的锁。当relative_time.count()<=0时 //将立即返回,就像调用try_lock()样。否则会阻塞,直到获取锁或超过给定的relative_time时间 //当锁被调用线程获取,返回true;反之,返回false. template<typename Rep, typename Period> bool try_lock_for(const std::chrono::duration<Rep, Period>& relative_time); //在指定的absolute_time时间内,尝试获取*this上的锁。当absolute_time<=clock::now()时 //将立即返回,就像调用try_lock()一样。否则会阻塞,直到获取锁或Clock::now()返回的 //时间等于或超过给定的absolute_time的时间。返回值含义与try_lock_for相同。 template<typename Clock, typename Duration> bool try_lock_until(const std::chrono::time_point<Clock, Duration>& absolute_time); }; //4. 带定时的递归互斥锁 class recursive_timed_mutex { public : recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; recursive_timed_mutex(); ~recursive_timed_mutex(); void lock(); void unlock(); bool try_lock() noexcept; template<typename Rep, typename Period> bool try_lock_for(const std::chrono::duration<Rep, Period>& relative_time); template<typename Clock, typename Duration> bool try_lock_until(const std::chrono::time_point<Clock, Duration>& absolute_time); };