C++核心准则CP.21:使用std::lock()或者std::scoped_lock获取多个...
共 1714字,需浏览 4分钟
·
2020-07-02 23:21
CP.21: Use std::lock() or std::scoped_lock to acquire multiple mutexes
CP.21:使用std::lock()或者std::scoped_lock获取多个mutex
Reason(原因)
To avoid deadlocks on multiple mutexes.
避免在多个mutex上发生死锁。
Example(实例)
This is asking for deadlock:
下面的代码会引发死锁:
// thread 1
lock_guard lck1(m1);
lock_guard lck2(m2);
// thread 2
lock_guard lck2(m2);
lock_guard lck1(m1);
Instead, use lock():
使用lock代替:
// thread 1
lock(m1, m2);
lock_guard lck1(m1, adopt_lock);
lock_guard lck2(m2, adopt_lock);
// thread 2
lock(m2, m1);
lock_guard lck2(m2, adopt_lock);
lock_guard lck1(m1, adopt_lock);
or (better, but C++17 only):
或者(可以更好,但仅限于C++17)
// thread 1
scoped_lock lck1(m1, m2);
// thread 2
scoped_lock lck2(m2, m1);
Here, the writers of thread1 and thread2 are still not agreeing on the order of the mutexes, but order no longer matters.
这里,thread1和thread2的作者仍然没有在获取mutex的顺序上取得一致,但是顺序已经不再重要。
Note(注意)
In real code, mutexes are rarely named to conveniently remind the programmer of an intended relation and intended order of acquisition. In real code, mutexes are not always conveniently acquired on consecutive lines.
在实际的代码中,mutex的命名很少能向程序员提示希望的关系和希望的请求次序。在实际的代码中,mute不会总是在相邻代码中执行获取,那样的话问题可能更容易被发现。
In C++17 it's possible to write plain
在C++17可以简单地这样写:
lock_guard lck1(m1, adopt_lock);
and have the mutex type deduced.
这样就可以实现mutex类型推断。
Enforcement(实施建议)
Detect the acquisition of multiple mutexes. This is undecidable in general, but catching common simple examples (like the one above) is easy.
检查多重mutex获取操作。这一点通常是不可判定的,但是捕捉一般的简单例子(例如上面的例子)是容易做到的。
原文链接https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#cp21-use-stdlock-or-stdscoped_lock-to-acquire-multiple-mutexes
觉得本文有帮助?请分享给更多人。
关注微信公众号【面向对象思考】轻松学习每一天!
面向对象开发,面向对象思考!