C++11中头文件 <mutex>

Mutex 类

std::mutex

最基本的 Mutex 类

  1. 构造函数,std::mutex不允许拷贝构造,最初产生的 mutex 对象是处于 unlocked 状态的。

  2. lock(),调用线程将锁住该互斥量。线程调用该函数会发生下面 3 种情况:
    (1). 如果该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用 unlock之前,该线程一直拥有该锁;
    (2). 如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住;
    (3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。

  3. unlock(), 解锁,释放对互斥量的所有权。

  4. try_lock(),尝试锁住互斥量,如果互斥量被其他线程占有,则当前线程也不会被阻塞。线程调用该函数也会出现下面 3 种情况:
    (1). 如果当前互斥量没有被其他线程占有,则该线程锁住互斥量,直到该线程调用 unlock 释放互斥量;
    (2). 如果当前互斥量被其他线程锁住,则当前调用线程返回 false,而并不会被阻塞掉;
    (3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。

1
2
3
4
5
std::mutex g_mutex;

g_mutex.lock();
//do something
g_mutex.unlock();

std::recursive_mutex

递归 Mutex 类,成员函数与std::mutex相同。

允许同一个线程对互斥量多次上锁(即递归上锁),来获得对互斥量对象的多层所有权,std::recursive_mutex 释放互斥量时需要调用与该锁层次深度相同次数的 unlock(),可理解为 lock() 次数和 unlock() 次数相同。

1
2
3
4
5
6
7
std::recursive_mutex remutex;

remutex.lock();
remutex.lock();
//do something
remutex.unlock();
remutex.unlock();

std::timed_mutex

定时 Mutex 类,比std::mutex多以下两个函数

  1. try_lock_for() 函数接受一个时间范围,表示在这一段时间范围之内线程如果没有获得锁则被阻塞住。如果在此期间其他线程释放了锁,则该线程可以获得对互斥量的锁,如果超时(即在指定时间内还是没有获得锁),则返回 false。
    与 std::mutex 的 try_lock() 不同,try_lock 如果被调用时没有获得锁则直接返回 false。

  2. try_lock_until() 函数则接受一个时间点作为参数,在指定时间点未到来之前线程如果没有获得锁则被阻塞住,如果在此期间其他线程释放了锁,则该线程可以获得对互斥量的锁,如果超时(即在指定时间内还是没有获得锁),则返回 false。

1
2
3
std::timed_mutex mtx;
mtx.try_lock_for(std::chrono::milliseconds(200)
mtx.unlock();

std::recursive_timed_mutex

定时递归 Mutex 类, 成员函数与std::timed_mutex相同

Lock 类

std::lock_guard

与 Mutex RAII 相关,方便线程对互斥量上锁。 与Mutex配合使用,把锁放到lock_guard中时,mutex自动上锁,lock_guard析构时,同时把mutex解锁.

1
2
3
4
5
6
7
8
9
10
std::mutex mMutex;

void EMCallSession::setConferenceId(const std::string& conferenceId)
{
//创建一个std::lock_guard局部变量,创建时传入的mMutex自动上锁
std::lock_guard<std::mutex> lock(mMutex);
mConferenceId = conferenceId;
}
//方法执行完毕,花括号关闭之前,mMutex自动解锁
//函数发生异常时,std::lock_guard会自动释放锁

std::unique_lock

与 Mutex RAII 相关,方便线程对互斥量上锁,提供了更好的上锁和解锁控制.

  1. owns_lock(): 是否拥有锁

    1
    2
    _LIBCPP_INLINE_VISIBILITY
    bool owns_lock() const _NOEXCEPT {return __owns_;}

  2. release(): 放弃对锁的关联,当析构时,不会unlock锁

    1
    2
    3
    4
    5
    6
    7
    8
    _LIBCPP_INLINE_VISIBILITY
    mutex_type* release() _NOEXCEPT
    {

    mutex_type* __m = __m_;
    __m_ = nullptr;
    __owns_ = false;
    return __m;
    }

Tag 类

与Lock 类相关,通常作为参数传到Lock 类的构造函数里

std::adopt_lock_t

已经获得了锁

源码解析:std::lock_guard

1
2
3
4
explicit lock_guard(mutex_type& __m)  
: __m_(__m) {__m_.lock();}
lock_guard(mutex_type& __m, adopt_lock_t)
: __m_(__m) {}

在构造函数中传入std::adopt_lock_t,会被认为已经获取到锁,不再进行获取锁的操作。

std::defer_lock_t

还没有获取到锁

std::try_to_lock_t

在Lock类构造时,尝试去获取锁




Published with Hexo and Theme by Kael
X