#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex m1;
mutex m2;
template<typename T>
void foo(const T& t){
m1.lock();
cout << t << '\n';
m1.unlock();
}
int main(){
thread t1{foo<string>,"lock m1"};
unique_lock<mutex> lck1{m1,defer_lock};
unique_lock<mutex> lck2{m2,defer_lock};
lock(lck1,lck2);
t1.join();
return 0;
}
非成员函数lock
旨在避免死锁,对吧?为什么我的程序仍然陷入僵局?
答案 0 :(得分:4)
下面
lock(lck1,lck2);
t1.join();
您锁定互斥锁m1
,然后等待t1
完成。
在t1
中,您还可以锁定m1
- 此处
m1.lock();
如果lock(lck1,lck2);
在m1.lock();
之前成功,那么t1
永远不会完成,因为main
已锁定m1
如果m1.lock();
在lock(lck1,lck2);
之前成功,程序将正常执行。
但是,您无法知道哪个锁成功。
答案 1 :(得分:1)
该函数旨在避免某些特定类型的死锁。它不能也不能完全避免死锁。
天真的实现可能只是锁定lck1
,然后是lck2
。如果另一个线程只是锁定lck2
,然后锁定lck1
,则可能存在死锁。这就是std::lock
旨在防止的情况。如果无法获取锁,它将阻止,但如果无法获取一个锁,则不会保留任何其他锁。