1.std::mutex
互斥锁:是为了保护共享数据
提共了三个接口:
lock()
try_lock()
unlock()
class mutex : private __mutex_base
{
public:
typedef __native_type* native_handle_type;
#ifdef __GTHREAD_MUTEX_INIT
constexpr
#endif
mutex() noexcept = default;
~mutex() = default;
mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;
void
lock()
{
int __e = __gthread_mutex_lock(&_M_mutex);
// EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
if (__e)
__throw_system_error(__e);
}
bool
try_lock() noexcept
{
// XXX EINVAL, EAGAIN, EBUSY
return !__gthread_mutex_trylock(&_M_mutex);
}
void
unlock()
{
// XXX EINVAL, EAGAIN, EPERM
__gthread_mutex_unlock(&_M_mutex);
}
native_handle_type
native_handle() noexcept
{ return &_M_mutex; }
};
2. std::shared_mutex
c++14中,有标准库 有shared_mutex
c++17中,有标准库shared_timed_mutex 库。
shared_mutex 又可以被成为读写锁,只允许一个线程对其加写锁,允许多个线程对其加读锁。
shared_mutex的接口
void lock() { _M_impl.lock(); }
bool try_lock() { return _M_impl.try_lock(); }
void unlock() { _M_impl.unlock(); }
// Shared ownership
void lock_shared() { _M_impl.lock_shared(); }
bool try_lock_shared() { return _M_impl.try_lock_shared(); }
void unlock_shared() { _M_impl.unlock_shared(); }
具体实现:
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <vector>
class data
{
mutable std::shared_mutex m_datalock;
vector<int> m_data;
void write_data(int inputdata)
{
std::lock_guard<std::shared_mutex> lk(m_datalock);//加写锁
m_data.emplace_back(inputdata);
}
int read_data(int slot)
{
std::shared_mutex<std::shared_mutex> lk(m_datalock);//加读锁
if(slot<m_data.size()-1)
{
return m_data[slot];
}
}
};
3.对mutex lock unlok操作封装的模板类
lock_guard() 源码:
构造函数加锁,构函数里解锁。
template<typename _Mutex>
class lock_guard
{
public:
typedef _Mutex mutex_type;
explicit lock_guard(mutex_type& __m) : _M_device(__m)
{ _M_device.lock(); }
lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
{ } // calling thread owns mutex
~lock_guard()
{ _M_device.unlock(); }
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
private:
mutex_type& _M_device;
};
unqique_lock() 是为了替代lock_guard,增加了lock_guard的灵活性。
它提供了三个构造函数:
unique_lock(mutex_type& __m, defer_lock_t) noexcept
: _M_device(std::__addressof(__m)), _M_owns(false)
{ }
unique_lock(mutex_type& __m, try_to_lock_t)
: _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
{ }
unique_lock(mutex_type& __m, adopt_lock_t) noexcept
: _M_device(std::__addressof(__m)), _M_owns(true)
{
// XXX calling thread owns mutex
}
std::defer_lock_t:只对mutex进行初始化。
std::try_to_lock_t: 不阻塞,可以立刻返回
std::adopt_lock_t :不进行加锁,析构函数可以进行解锁。