今天跑步的时候,想起前一阵被问到的死锁问题还没有好好的看过,刚好简书上有一篇比较细致的文章,这里做下总结.
文章链接:
https://www.jianshu.com/p/cab2fbc4b794
总结:
1.这里死锁产生的原因,线程t1等待t2释放mtB,而线程t2等待t1释放mtA.
2.死锁解决的办法:让这两个互斥量同时上锁,然后通过adopt_lock参数来在后面能够正确释放.
ps:一个官方的例子
:https://zh.cppreference.com/w/cpp/thread/lock_tag
//为什么需要采用两个互斥量,不可以使用一个互斥量,然后在函数最开始进行加锁,然后在函数结束时进行解锁码?? #include <mutex> #include <thread> #include<iostream> using namespace std; struct bank_account { explicit bank_account(int balance) : balance(balance) {} int balance; std::mutex m; }; void transfer(bank_account &from, bank_account &to, int amount) { // 锁定两个互斥而不死锁 std::lock(from.m, to.m); // 保证二个已锁定互斥在作用域结尾解锁 std::lock_guard<std::mutex> lock1(from.m, std::adopt_lock); std::lock_guard<std::mutex> lock2(to.m, std::adopt_lock); // 等价方法: // std::unique_lock<std::mutex> lock1(from.m, std::defer_lock); // std::unique_lock<std::mutex> lock2(to.m, std::defer_lock); // std::lock(lock1, lock2); from.balance -= amount; to.balance += amount; } int main() { bank_account my_account(100); bank_account your_account(50); std::thread t1(transfer, std::ref(my_account), std::ref(your_account), 10); std::thread t2(transfer, std::ref(your_account), std::ref(my_account), 5); t1.join(); t2.join(); cout << "my_account:" << my_account.balance << endl; cout << "your_account:" << your_account.balance << endl; }