C++ mutex

std::mutex

Since C++ 11

1
#include <mutex>
1
2
mutex(const mutex&)            = delete; // copy constructor
mutex& operator=(const mutex&) = delete; // copy operator

最基本的互斥锁。默认 unlocked。不可拷贝、赋值、移动。

lock:调用线程将锁住该互斥量;如果互斥量被其他线程占有,则当前线程会被阻塞;当前线程在未解锁的情况下重复lock会产生死锁(deadlock)
try_lock:尝试锁住互斥量;如果互斥量被其他线程占有,则当前线程也不会被阻塞,函数返回 false;当前线程在未解锁的情况下重复try_lock会产生死锁(deadlock)
unlock:解锁

std::recursive_mutex

Since C++ 11

1
#include <mutex>
1
2
recursive_mutex(const recursive_mutex&)            = delete;
recursive_mutex& operator=(const recursive_mutex&) = delete;

递归互斥锁,允许多次上锁,解锁时也需要多次解锁,即lockunlock次数相同。

首次加锁的线程可以多次加锁,其它线程会阻塞;解锁时也需要多次解锁。可解决同一个线程死锁的问题。

其它特性与 std::mutex 类似。

std::time_mutex

Since C++ 11

1
#include <mutex>
1
2
timed_mutex(const timed_mutex&)            = delete;
timed_mutex& operator=(const timed_mutex&) = delete;

try_lock_for函数接受一个时间范围作为参数,在时间范围内线程如果没有获得锁则被阻塞住,如果在此期间其他线程释放了锁,则该线程可以获得互斥锁,如果超时,则返回 false。
try_lock_until函数接受一个时间点作为参数,在指定时间点到来之前线程如果没有获得锁则被阻塞住,如果在此期间其他线程释放了锁,则该线程可以获得互斥锁,如果超时,则返回 false。

其它特性与 std::mutex 类似。

std::recursive_timed_mutex

Since C++ 11

1
#include <mutex>
1
2
recursive_timed_mutex(const recursive_timed_mutex&)            = delete;
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

结合 std::recursive_mutexstd::time_mutex 特性。

std::shared_mutex

Since C++ 17

1
#include <shared_mutex>
1
2
3
4
5
6
7
8
9
10
shared_mutex(const shared_mutex&)            = delete;
shared_mutex& operator=(const shared_mutex&) = delete;

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

void lock_shared() noexcept;
bool try_lock_shared() noexcept;
void unlock_shared() noexcept;

写线程以独占模式持有锁,读取线程可以同时持有锁。

写线程持有锁,其它读、写线程均阻塞等待;
读线程持有锁,其它读线程可以同时持有锁,写线程阻塞等待。

std::lock_guard

Since C++ 11

1
#include <mutex>
1
2
lock_guard(const lock_guard&)            = delete;
lock_guard& operator=(const lock_guard&) = delete;

不支持主动解锁,需要等析构时自动解锁。

std::unique_lock

Since C++ 11

1
#include <mutex>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unique_lock() noexcept = default;

unique_lock(_Mutex& _Mtx); // construct and lock
unique_lock(_Mutex& _Mtx, adopt_lock_t) noexcept; // construct and assume already locked
unique_lock(_Mutex& _Mtx, defer_lock_t) noexcept; // construct but don't lock
unique_lock(_Mutex& _Mtx, try_to_lock_t); // construct and try to lock (try_lock)
unique_lock(_Mutex& _Mtx, const chrono::duration<_Rep, _Period>& _Rel_time); // construct and lock with timeout (try_lock_for)
unique_lock(_Mutex& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time); // construct and lock with timeout (try_lock_until)

unique_lock(unique_lock&& _Other) noexcept; // move constructor
unique_lock& operator=(unique_lock&& _Other) noexcept; // move operator

unique_lock(const unique_lock&) = delete; // copy constructor
unique_lock& operator=(const unique_lock&) = delete; // copy operator

void lock();
bool try_lock();
void unlock();
bool try_lock_for(const chrono::duration<_Rep, _Period>& _Rel_time);
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time);

支持主动解锁;不可拷贝、赋值;可移动;不锁定、超时锁。

通过构造函数可以看出,unique_lock与不同类型的mutex搭配使用,会产生不同的特性。
shared_mutex搭配使用,对象构造时自动对shared_mutex加写锁,析构时自动解写锁。写独占。

std::shared_lock

Since C++ 14

1
#include <shared_mutex>
1
2
shared_lock(const shared_lock&)            = delete;
shared_lock& operator=(const shared_lock&) = delete;

shared_mutex配合使用,对象构造时自动对shared_mutex加读锁,析构时自动对shared_mutex解读锁。读共享。

std::scoped_lock

Since C++ 17

1
#include <mutex>
1
2
3
4
5
scoped_lock(_Mutexes&... _Mtxes);                        // construct and lock
scoped_lock(adopt_lock_t, _Mutexes&... _Mtxes) noexcept; // construct but don't lock

scoped_lock(const scoped_lock&) = delete;
scoped_lock& operator=(const scoped_lock&) = delete;

std::lock

Since C++ 11

1
#include <mutex>
1
2
std::mutex mtx1, mtx2;
std::lock(mtx1, mtx2);

用算法避免死锁。

Reference


C++ mutex
https://laplac2.github.io/cpp/mutex/
作者
Laplace
发布于
2024年5月9日
许可协议