mutex
mutex互斥量用来以独占方式访问资源。
操作 | 作用 |
---|---|
mutex m | 默认构造函数,构建一个未锁定的mutex对象 |
~mutex() | 析构函数 |
m.lock() | 尝试锁住mutex。如果mutex已是锁定状态,会造成阻塞 |
m.try_lock() | 尝试锁住mutex,成功则返回true |
m.try_lock_for(dur) | 尝试在时间段dur内锁住mutex,成功则返回true |
m.try_lock_until(tp) | 尝试在时间点tp之前锁住mutex,成功则返回true |
m.unlock() | 解锁mutex |
m.native_handle() |
lock_guard
mutex可以单独使用,但更好的是搭配lock_guard使用。
lock_guard可以确保一个locked mutex在离开lock_guard作用域时总会被解锁。
操作 | 作用 |
---|---|
lock_guard lg(m) | 为mutex对象构建一个lock_guard,并锁定mutex对象 |
lock_guard(m, adopt_lock) | 为已经锁定的mutex对象构建一个lock_guard |
~lock_guard() | 析构函数,解锁mutex对象 |
recursive_mutex
循环互斥量recursive_mutex允许在同一个线程内多次调用lock()而不会引起阻塞,在调用一次unlock()后解锁mutex。
std::lock()和std::try_lock()
有时候一个线程需要同时锁定多个mutex,如果对多个mutex进行逐一锁定可能会引起问题:锁住了m1但在m2阻塞了;如果以不同的次序锁住相同的mute还可能引起死锁。
mutex m1;
mutex m2;
lock_guard<mutex> lg1(m1);
lock_guard<mutex> lg2(m2);
lock()处理多个mutex时,只有当所有mutex对象都是释放状态,才会把所有mutex锁住,否则会阻塞直到所有mutex变成释放状态。
mutex m1;
mutex m2;
{
// 如果m1在另一线程中被锁住,lock不会单独锁住m2
// 而是等待m1被释放后,再同时锁住m1、m2
lock(m1, m2);
lock_guard<mutex> lg1(m1, adopt_lock);
lock_gurad<mutex> lg2(m2, adopt_lock);
}
try_lock()不会引起阻塞,当所有mutex对象都被成功锁定后返回-1,否则返回第一个锁住失败的mutex对象下标。