互斥量
mutex
互斥量
互斥算法避免多个线程同时访问共享资源。这会避免数据竞争,并提供线程间的同步支持。 4 种互斥量类型
mutex
基本互斥量,mutex
变量上锁后,在一个时间段内,只允许一个线程访问他。
class mutex;
特点
- 提供排他性非递归所有权语义:
- 调用方线程从成功调用
lock
或try_lock
开始,到他调用unlock
为止,占用mutex
- 其他线程若试图要求被占用的
mutex
的所有权时,将阻塞 (lock
) 或受到False
返回值 (try_lock
) - 调用方在调用
lock
或try_lock
前必须不占有 mutex
- 调用方线程从成功调用
- 若
mutex
在仍被占有时被销毁,或占有mutex
时线程终止,则行为未定义 mutex
既不可复制也不可移动
成员函数(部分)
lock()
: 要求获取锁,若锁已被另一线程获取,则将阻塞进程直到获得锁。若lock
被已占有锁mutex
的线程调用,则行为未定义,例如可能导致死锁或抛出std::system_error
。在抛出错误时,不锁定锁try_lock()
: 尝试锁定锁,立即返回,成功时返回true
,否则返回false
。已占有锁的线程调用该锁的 try_lock,行为未定义。unlock()
: 解锁互斥 ,互斥必须为当前线程所锁定,否则行为为定义
timed_mutex
类似mutex
,提供排他性非递归所有权语义,另外提供通过try_lock_for()
与try_lock_until()
方法试图带时限地要求timed_mutex
所有权。
class timed_mutex;
成员函数(部分)
try_lock_for()
: 尝试给互斥上锁。阻塞直到经过指定的timeout_duration
或者得到锁。成功获得锁后返回true
,否则返回false
- 若
timeout_duration
小于或等于timeout_duration.zero()
,则函数表现同try_lock()
- 若
try_lock_until()
: 尝试给锁互斥,阻塞直到抵达指定的timeout_time
或得到锁,成功得到锁时返回true
,否则返回false
recursive_mutex
递归锁
class recursive_mutex;
特点
- 提供排他性递归所有权语义:
- 调用方线程在从它成功锁互斥开始的时期占有
recursive_mutex
,在此期间,线程可进行对lock
或try_lock
的附加调用。所有权的时期在线程调用unlock
匹配次数时结束 - 其他线程试图要求被占有的
recursive_mutex
时,被阻塞或受到false
返回值 - 可锁定
recursive_mutex
次数的最大值是未指定的,但抵达该数后,对 lock 的调用将抛出std::system_error
,而对try_lock
的调用将返回false
- 调用方线程在从它成功锁互斥开始的时期占有
recursive_timed_mutex
定时递归互斥锁
class recursive_timed_mutex;
通用互斥管理
lock_guard
互斥体包装器,为在作用域期间占有互斥提供便利 RAII 风格机制。创建时,获取提供的互斥锁的所有权,控制流离开lock_guard
作用域时,自动析构并释放互斥量
template< class Mutex >
class lock_guard;
特点
- 创建即加锁,作用域结束自动析构,无需手动解锁
- 不能中途解锁,必须等待作用域结束
- 不能复制
(C++17 起,std::scoped_lock
给出lock_guard
的一种替代,有避免死锁的算法提供锁定多个互斥体的能力)
unique_lock
通用互斥包装器,允许延迟锁定、锁定的有时限尝试、递归锁定、所有权转移和与条件变量一同使用。
template< class Mutex >
class unique_lock;
特点
- 创建时可以不锁定
- 随时加锁解锁
- 作用域规则同
lock_guard
,析构自动释放锁 - 不可复制,可移动
- 条件变量
condition_variable
需要该类型的锁为参数
成员函数(部分)
operator=
: 若占有则解锁互斥,并取得另一者的所有权swap()
: 与另一unique_lock
交换状态release()
: 将关联的互斥解关联而不解锁它,并返回互斥的指针,若无关联的互斥,则返回空指针mutex()
: 返回指向关联互斥的指针,若无关联互斥,则返回空指针owns_lock()
: 检查*this
是否占有锁定的互斥,若拥有关联互斥且已获得其所有权则为true
,否则为false
operator bool
: 等效调用owns_lock()
指定锁定策略的标签常量
defer_lock
:defer_lock_t
的实例,不获得互斥的所有权try_to_lock
:try_to_lock_t
的实例,尝试获得互斥所有权而不阻塞adopt_lock_t
:adopt_lock_t
的实例,假设调用方线程已拥有互斥的所有权