std::scoped_lock 或 std::unique_lock 或 std::lock_guard?
std::scoped_lock or std::unique_lock or std::lock_guard?
从问题中我了解到std::scoped_lock
是"a strictly superior version of std::lock_guard
"。
从 this question I understand that "std::lock_guard
and std::unique_lock
are the same" except that std::unique_lock
has some extra features (eg. try_lock
) 以一些额外的开销为代价。
std::scoped_lock
与std::unique_lock
相比如何?
一些相关的问题,希望能得到这个问题的解答。
std::scoped_lock
和std::unique_lock
有什么区别?
- 在什么情况下应该使用
std::scoped_lock
而不是std::unique_lock
?
- 什么情况下应该使用
std::unique_lock
而不是std::scoped_lock
?
- 为什么
std::scoped_lock
没有实现 std::unique_lock
的一些附加功能?
这两个对象用于不同的目的。 scoped_lock
适用于想要以无死锁方式锁定一定数量的互斥对象的简单情况。锁定单个互斥量只是锁定多个互斥量的一种特殊情况。物体完全不动,非常简单
unique_lock
提供了许多功能,其中很少有在同时锁定 多个 互斥体时特别适用。
延迟锁定。推迟必须是全部或全部;您要么延迟锁定所有互斥锁,要么延迟锁定其中的none。不清楚为什么要延迟锁定一系列互斥量,因为如果其中任何一个失败,您将不得不放弃任何成功的锁定。
超时锁定。如果您想要 100 毫秒的超时,这是否意味着锁定所有互斥体的时间不应超过 100 毫秒?即如果第一个3立即加锁,但是下一个需要75ms,如果第五个需要30ms是否应该认为是超时?
采用互斥锁。在单个操作中锁定多个互斥锁的全部意义在于能够避免死锁。这是通过以全局一致的顺序锁定互斥锁来完成的。也就是说,任何用 std::lock
等效调用锁定这些互斥对象的地方都会以相同的顺序锁定它们,无论如何。
如果其中一个互斥量已经被锁定(因此应该采用锁定),则它被锁定在 std::lock
之外,因此您无法保证它被锁定在全局一致命令。这忽略了指定采用哪些互斥量和锁定哪些互斥量的困难。
所有权转让(可移动)。由于与采用锁类似的原因,对于多个互斥体来说,这是一个可疑的前景。仅当对 std::lock
或等效项的单个调用锁定了所有感兴趣的互斥量时,防止死锁的保证才有效。如果您要移动这些 scoped_lock
的所有权,那么很容易在代码中的某个点上有多个 scoped_lock
在同一范围内,而您本可以锁定所有这些 scoped_lock
一气呵成。这会引发 std::lock
旨在避免的那种僵局。
请注意 std::lock
(scoped_lock
功能的基础)甚至没有尝试提供任何这些功能。
是否可以对 scoped_lock
进行专门化,它只采用一种提供 unique_lock
行为的互斥锁类型?当然。但这会违反 scoped_lock
的目的,即成为多个互斥体的死锁安全储物柜。它只是意外地废弃了 lock_guard
,因为它在单个互斥锁的情况下具有相同的接口。
此外,具有截然不同的接口和功能的模板专业化通常效果不佳。以 vector<bool>
为例。
从std::scoped_lock
是"a strictly superior version of std::lock_guard
"。
从 this question I understand that "std::lock_guard
and std::unique_lock
are the same" except that std::unique_lock
has some extra features (eg. try_lock
) 以一些额外的开销为代价。
std::scoped_lock
与std::unique_lock
相比如何?
一些相关的问题,希望能得到这个问题的解答。
std::scoped_lock
和std::unique_lock
有什么区别?- 在什么情况下应该使用
std::scoped_lock
而不是std::unique_lock
? - 什么情况下应该使用
std::unique_lock
而不是std::scoped_lock
? - 为什么
std::scoped_lock
没有实现std::unique_lock
的一些附加功能?
这两个对象用于不同的目的。 scoped_lock
适用于想要以无死锁方式锁定一定数量的互斥对象的简单情况。锁定单个互斥量只是锁定多个互斥量的一种特殊情况。物体完全不动,非常简单
unique_lock
提供了许多功能,其中很少有在同时锁定 多个 互斥体时特别适用。
延迟锁定。推迟必须是全部或全部;您要么延迟锁定所有互斥锁,要么延迟锁定其中的none。不清楚为什么要延迟锁定一系列互斥量,因为如果其中任何一个失败,您将不得不放弃任何成功的锁定。
超时锁定。如果您想要 100 毫秒的超时,这是否意味着锁定所有互斥体的时间不应超过 100 毫秒?即如果第一个3立即加锁,但是下一个需要75ms,如果第五个需要30ms是否应该认为是超时?
采用互斥锁。在单个操作中锁定多个互斥锁的全部意义在于能够避免死锁。这是通过以全局一致的顺序锁定互斥锁来完成的。也就是说,任何用
std::lock
等效调用锁定这些互斥对象的地方都会以相同的顺序锁定它们,无论如何。如果其中一个互斥量已经被锁定(因此应该采用锁定),则它被锁定在
std::lock
之外,因此您无法保证它被锁定在全局一致命令。这忽略了指定采用哪些互斥量和锁定哪些互斥量的困难。所有权转让(可移动)。由于与采用锁类似的原因,对于多个互斥体来说,这是一个可疑的前景。仅当对
std::lock
或等效项的单个调用锁定了所有感兴趣的互斥量时,防止死锁的保证才有效。如果您要移动这些scoped_lock
的所有权,那么很容易在代码中的某个点上有多个scoped_lock
在同一范围内,而您本可以锁定所有这些scoped_lock
一气呵成。这会引发std::lock
旨在避免的那种僵局。
请注意 std::lock
(scoped_lock
功能的基础)甚至没有尝试提供任何这些功能。
是否可以对 scoped_lock
进行专门化,它只采用一种提供 unique_lock
行为的互斥锁类型?当然。但这会违反 scoped_lock
的目的,即成为多个互斥体的死锁安全储物柜。它只是意外地废弃了 lock_guard
,因为它在单个互斥锁的情况下具有相同的接口。
此外,具有截然不同的接口和功能的模板专业化通常效果不佳。以 vector<bool>
为例。