[英]std::scoped_lock behaviour with a single mutex
语境:
我知道自从带有std::scoped_lock
的c++17到来以来, std::lock_guard
变得有点过时了。
我也知道std::scoped_lock
是首选,因为它可以处理多个互斥体并使用与std::lock
相同的死锁避免算法。
我在这里对我们只有一个互斥锁的情况感兴趣,因此我们不需要关心避免死锁。
我从这个答案中读到:
您可以考虑不推荐使用
std::lock_guard
。std::scoped_lock
的单参数情况可以作为std::scoped_lock
来实现,这样您就不必担心可能出现的性能问题。
题:
我想知道这句话有多少是真的。
我的意思是,是否保证(根据标准)使用单个互斥锁, std::scoped_lock
将被专门化,以便消除由于死锁避免处理而产生的任何不必要的开销?
我的想法:
经过对该问题的一些调查,我从cppreference 中找到了以下句子:
如果给出了多个互斥体,则使用死锁避免算法,就像
std::lock
。
这可以让我们推断出这样的事情不会发生(即如果只给出一个互斥锁)。
但再一次,这只是一个假设。
从这个c++ 草案中,我没有看到任何关于这种专业化的明确提及。
我得到的唯一一句话是:
当
sizeof...(MutexTypes)
为1
,提供的Mutex
类型应满足Cpp17BasicLockable要求。 否则,每个互斥类型都应满足Cpp17Lockable要求。
(强调我的)
我知道BasicLockable要求要求存在满足此处定义的条件的lock()
和unlock()
函数。
在另一方面中,可锁定要求假设与加入的BasicLockable要求try_lock()
其满足条件,如定义的函数那里。
我知道需要try_lock()
函数才能运行std::lock
使用的死锁避免算法。
根据上述c++草案摘录中所述,如果我们只给std::scoped_lock
一个互斥锁,则不需要try_lock()
函数。
这是否足以推断/考虑始终定义上述专业化(并且可能表现得像std::lock_guard
会做的那样)。
我会说是的,但因为我从未看到任何明确提及它,我想知道我是对的还是我错过了什么?
编辑:
效果:用
tie(m...)
初始化pm
。 然后,如果sizeof...(MutexTypes)
为0
,则没有效果。 否则,如果sizeof...(MutexTypes)
为1
,则m.lock()
。 否则,lock(m...)
。
(强调我的)
这回答了我的询问,只有在有多个给定的互斥std::lock
才会调用std::lock
。 在问这个问题之前我应该看到它...
当仅提供一个互斥锁时,要求std::scoped_lock
行为与std::lock_guard
相同。 因此对单个互斥体的情况有不同的要求。
这可以通过专门化来完成,也可以通过不同的内部机制来完成,只要行为是相同的。
如果您阅读了lock_guard
的规范(就在scoped_lock
),那应该很清楚。
用 m 初始化 pm。 调用 m.lock()
用 tie(m...) 初始化 pm。 [...] 否则如果 sizeof...(MutexTypes) 为 1,则 m.lock()。 [...]
它没有明确提到使用lock_guard
但需要具有相同的行为。
该标准很少通过专业化来保证某种优化(值得注意的例子是对不同迭代器类型的专业化和std::vector<bool>
可恶之处)。 为此,有两种方法:
try_lock
,那么为什么它不应该是有效的。scoped_lock
是否在你的代码的热门路径上,如果你真的认为(并有数据证明) scoped_lock
很慢,那么然后才用lock_guard
替换它并再次测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.