如何使用非成员函数锁

时间:2016-05-01 09:30:01

标签: c++ concurrency

#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旨在避免死锁,对吧?为什么我的程序仍然陷入僵局?

2 个答案:

答案 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旨在防止的情况。如果无法获取锁,它将阻止,但如果无法获取一个锁,则不会保留任何其他锁。