Mutex介绍

Mutex 又称互斥量,C++11 中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mutex> 头文件中,所以如果你在程序里面使用 std::mutex 及相关类型和辅助函数,就必须包含 <mutex> 头文件。

C++11 中定义了如下与互斥量和锁相关的类:

  • Mutex 系列类(四种),C++11 标准中规定的与互斥量相关的类包括:

    1. std::mutex,最基本的 Mutex 类,该类提供了最基本的上锁和解锁操作。同时,基本的互斥量不允许某个线程在已获得互斥量的情况下重复对该互斥量进行上锁操作,所以重复上锁将会导致死锁(结果通常未定义的)。
    2. std::recursive_mutex,递归 Mutex 类,与 std::mutex 功能基本相同,但是允许互斥量的拥有者(通常是某个线程)重复对该互斥量进行上锁操作而不会产生死锁,但必须保证上锁和解锁的次数相同。
    3. std::time_mutex,定时 Mutex 类,与 std::mutex 功能基本相同,但是提供了两个额外的定时上锁操作,try_lock_fortry_lock_until,即某个线程在规定的时间内对互斥量进行上锁操作,如果在规定的时间内获得了锁则返回 true, 超时则返回 false,在本章后面的内容中我会介绍try_lock_fortry_lock_until两个上锁函数之间细微的差异。
    4. std::recursive_timed_mutex,定时递归 Mutex 类,既提供了重复上锁功能,又提供了定时上锁的特性(即在规定的时间内没有获得锁则返回 false),相当于 std::recursive_mutexstd::time_mutex 的组合。
  • Lock 类(两种),C++11 标准中定义了两种与互斥量相关的 RAII 技术。(RAII : Resource Acquisition Is Initialization,资源获取即初始化)

    1. std::lock_guard,与 Mutex RAII 相关,方便线程对互斥量上锁。
    2. std::unique_lock,与 Mutex RAII 相关,方便线程对互斥量上锁,但提供了更好的上锁和解锁控制。
  • 其他类型

    1. std::once_flagcall_once 辅助函数会使用到该类型的对象。
    2. (默认) 无请求锁,阻塞当前线程直到成功获得锁。
    3. std::defer_lock std::defer_lock_t 不请求锁。
    4. std::try_to_lock std::try_to_lock_t 尝试请求锁,但不阻塞线程,锁不可用时也会立即返回。std::adopt_lock std::adopt_lock_t 假定当前线程已经获得互斥对象的所有权,所以不再请求锁。
  • 辅助函数

    1. std::try_lock,尝试同时对多个互斥量上锁。
    2. std::lock,同时对多个互斥量上锁。
    3. std::call_once,如果多个线程需要同时调用某个函数,call_once 可以保证多个线程对该函数只调用一次。

本章后面会对以上类型和函数进行详细介绍,我们首先来看 <mutex> 头文件中各个类型的摘要吧。

4.1 <mutex> 头文件摘要

<mutex> 头文件摘要如下:

namespace std {
    
    class mutex;
    class recursive_mutex;
    class timed_mutex;
    class recursive_timed_mutex;

    struct defer_lock_t { };
    struct try_to_lock_t { };
    struct adopt_lock_t { };

    constexpr defer_lock_t defer_lock { };
    constexpr try_to_lock_t try_to_lock { };
    constexpr adopt_lock_t adopt_lock { };

    template <class Mutex> class lock_guard;
    template <class Mutex> class unique_lock;

    template <class Mutex>
    void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y);

    template <class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
    template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);

    struct once_flag {
        constexpr once_flag() noexcept;
        once_flag(const once_flag&) = delete;
        once_flag& operator=(const once_flag&) = delete;
    };

    template<class Callable, class ...Args>
    void call_once(once_flag& flag, Callable func, Args&&... args);
}

4.1.1 std::mutex 类摘要

namespace std {
    class mutex {
        public:
            constexpr mutex();
            ~mutex();
            mutex(const mutex&) = delete;
            mutex& operator=(const mutex&) = delete;

            void lock();
            bool try_lock() noexcept;
            void unlock() noexcept;

            typedef implementation-defined native_handle_type;
            native_handle_type native_handle();
    };
}

4.1.2 std::recursive_mutex 类摘要

namespace std {
    class recursive_mutex {
        public:
            recursive_mutex();
            ~recursive_mutex();
            recursive_mutex(const recursive_mutex&) = delete;
            recursive_mutex& operator=(const recursive_mutex&) = delete;

            void lock();
            bool try_lock() noexcept;
            void unlock() noexcept;

            typedef implementation-defined native_handle_type;
            native_handle_type native_handle();
    };
}

4.1.3 std::timed_mutex 类摘要

namespace std {
    class timed_mutex {
        public:
            timed_mutex();
            ~timed_mutex();
            timed_mutex(const timed_mutex&) = delete;
            timed_mutex& operator=(const timed_mutex&) = delete;

            void lock();
            bool try_lock();
            template <class Rep, class Period>
            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) noexcept;
            template <class Clock, class Duration>
            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) noexcept;
            void unlock();

            typedef implementation-defined native_handle_type; 
            native_handle_type native_handle();    
    };
}

4.1.4 std::recursive_timed_mutex 类摘要

namespace std {
    class recursive_timed_mutex {
        public:
            recursive_timed_mutex();
            ~recursive_timed_mutex();
            recursive_timed_mutex(const recursive_timed_mutex&) = delete;
            recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

            void lock();
            bool try_lock();
            template <class Rep, class Period>
            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) noexcept;
            template <class Clock, class Duration>
            bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) noexcept;
            void unlock();

            typedef implementation-defined native_handle_type; 
            native_handle_type native_handle();
    };
}

4.1.5 lock_guard 类摘要

    template<class _Mutex>
    class lock_guard
    {	// class with destructor that unlocks a mutex
    public:
        using mutex_type = _Mutex

        explicit lock_guard(_Mutex& _Mtx)
            : _MyMutex(_Mtx)
        {	// construct and lock
            _MyMutex.lock();
        }
        lock_guard(_Mutex& _Mtx, adopt_lock_t)
            : _MyMutex(_Mtx)
        {	// construct but don't lock
        }
        ~lock_guard() noexcept/ unlock
            _MyMutex.unlock(
        {	/);
        }
        lock_guard(const lock_guard&) = delete;
        lock_guard& operator=(const lock_guard&) = delete;
    private:
        _Mutex& _MyMutex;
    };
    */

4.1.6 std::unique_lock 类摘要

namespace std {
    template <class Mutex>
    class unique_lock {
        public:
            typedef Mutex mutex_type;
            // 构造/拷贝/析构:
            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) noexcept;
            unique_lock(mutex_type& m, adopt_lock_t) noexcept;
            template <class Clock, class Duration>
            unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time) noexcept;
            template <class Rep, class Period>
            unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time) noexcept;
            ~unique_lock();
            unique_lock(unique_lock const&) = delete;
            unique_lock& operator=(unique_lock const&) = delete;
            unique_lock(unique    _lock&& u) noexcept;
            unique_lock& operator=(unique_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(unique_lock& u) noexcept;
            mutex_type *release() noexcept;

            // observers:
            bool owns_lock() const noexcept;
            explicit operator bool () const noexcept;
            mutex_type* mutex() const noexcept;
        private:
            mutex_type *pm; // exposition only
            bool owns; // exposition only
    };
    
    template <class Mutex>
    void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九五一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值