继续 Concurrency In Action我已经达到了下面的例子。
作者指出,如果我们每次都锁定 2 mutexes同样的顺序,那么我们保证避免deadlocks .
考虑书中的这个例子:
class X
{
private:
some_big_object some_detail;
std::mutex m;
public:
X(some_big_object const& sd):some_detail(sd){}
friend void swap(X& lhs, X& rhs)
{
if(&lhs==&rhs){return;}
std::lock(lhs.m,rhs.m);
std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock);
std::lock_guard<std::mutex> lock_b(rhs.m,std::adopt_lock);
swap(lhs.some_detail,rhs.some_detail);
}
};
- 我们为什么应用
std::lock
然后应用 2std::lock_guards
与std::adopt_lock
而不是一个接一个地应用 2 个std::lock_guards
? - 为什么我们不能把这个 2
std::mutex
es 在std::scoped_lock
??
最佳答案
Why do we apply the std::lock and then apply 2 std::lock_guards with std::adopt_lock instead of just applying 2 std::lock_guards one after another??
如果你使用两个 std::lock_guard
没有 std::lock
swap(a, b);
的锁定顺序与 swap(b, a);
相反,其中 a
和 b
是 X
。如果一个线程尝试 swap(a, b);
而另一个线程尝试 swap(b, a);
它们可能会死锁。第一个线程将拥有 a
的互斥锁并等待 b
的互斥锁,而第二个线程将拥有 b
的锁s mutex 并等待 a
。使用 std::lock
确保锁定顺序始终一致。
Why cant we just put this 2 std::mutexes in the std::scoped_lock??
如果您查看所链接文章的发布日期,c++17 还不存在。自 std::scoped_lock
是c++17引入的,不可能在文章中用到。这种锁定问题是 std::scoped_lock
旨在解决的问题,应该在现代代码中使用。
关于c++ - 为什么要把 std::lock 放在 std::lock_guard 之前,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50046067/