【发布时间】:2020-01-29 12:11:10
【问题描述】:
上下文:
我知道自从c++17 和std::scoped_lock 一起出现以来,std::lock_guard 已经被弃用了。
我也知道std::scoped_lock 是首选,因为它可以处理多个互斥体,并使用与std::lock 相同的死锁避免算法。
我对我们只有一个互斥体的情况感兴趣,因此我们不需要关心避免死锁。
我从this answer 读到:
您可以认为
std::lock_guard已弃用。std::scoped_lock的单参数案例可以实现为特化,这样您就不必担心可能出现的性能问题。
问题:
我想知道这句话有多少是真的。
我的意思是,是否保证(按标准)使用单个互斥锁,std::scoped_lock 将被专门化,以便消除由于避免死锁处理而导致的任何不必要的开销?
我的想法:
对问题进行了一番调查,我从cppreference找到了以下句子:
如果给定了多个互斥锁,则使用死锁避免算法,就像
std::lock一样。
这可以让我们推断出这样的事情不会发生(即如果只给出一个互斥锁)。
但再一次,这只是一个假设。
在c++ draft 中,我没有看到任何关于这种专业化的明确提及。
我得到的唯一一句话是:
当
sizeof...(MutexTypes)为1时,提供的Mutex类型应满足Cpp17BasicLockable 要求。否则,每个互斥锁类型都应满足 Cpp17Lockable 要求。
(强调我的)
我知道 BasicLockable 要求要求存在满足 here 等条件的 lock() 和 unlock() 函数。
另一方面,Lockable 要求假定 BasicLockable 要求,并添加了满足 there 等条件的 try_lock() 函数。
我知道try_lock() 函数是运行std::lock 使用的死锁避免算法所必需的。
根据上述c++ 草稿摘录中所述,如果我们只给std::scoped_lock 提供一个互斥锁,则不需要try_lock() 函数。
这是否足以推断/考虑始终定义上述专业化(并且可能表现得像 std::lock_guard 那样)。
我会说是的,但由于我从未看到任何明确提及它,我想知道我是对的还是我错过了什么?
编辑:
我刚刚注意到我错过了最重要的部分here,它指出:
效果:用
tie(m...)初始化pm。那么如果sizeof...(MutexTypes)是0,则没有效果。否则如果sizeof...(MutexTypes)是1,那么m.lock()。 否则,lock(m...)。
(强调我的)
这回答了我的询问,std::lock 仅在存在多个给定互斥体时才被调用。我应该在问问题之前看到它......
【问题讨论】:
标签: c++17 c++ c++ language-lawyer c++17 mutex scoped-lock