假定我们需要同时获取多个锁,那么std::lock函数和std::scope_lock<>模板可以帮助防范死锁。
class some_bi_obj;
void swap(some_bi_obj& lhs, some_bi_obj& rhs);
class X {
private:
some_bi_obj some_details;
std::mutex m;
public:
X(some_bi_obj const& sd) : some_details(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); // 指明mutex已经被锁了
std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock); // 指明mutex已经被锁了
swap(lhs.some_details, rhs.some_details);
}
};
或者使用scope_lock也可以
一个函数如果要锁住相同类型的多个对象,为了保证始终按相同的顺序加锁,我们可以比较mutex对象的地址,始终先加锁地址较小的mutex。
#include <iostream> #include <mutex> // 定义两个互斥锁对象 std::mutex mutex1; std::mutex mutex2; void lockMutexesInOrder(std::mutex* mutexA, std::mutex* mutexB) { // 比较锁对象的地址,将较小地址的锁先锁住 if (mutexA < mutexB) { mutexA->lock(); mutexB->lock(); } else { mutexB->lock(); mutexA->lock(); } } void unlockMutexes(std::mutex* mutexA, std::mutex* mutexB) { // 解锁两个互斥锁 mutexA->unlock(); mutexB->unlock(); } int main() { // 使用函数按顺序加锁和解锁两个互斥锁 lockMutexesInOrder(&mutex1, &mutex2); // 此处放置需要在拥有锁的情况下执行的代码 unlockMutexes(&mutex1, &mutex2); return 0; }
No comments yet.