How to use the non-member function lock

advertisements
#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;
}

The non-member function lock is designed to avoid deadlocks, right? Why my program is still deadlocked?


The function is designed to avoid some specific types of deadlocks. It doesn't and cannot avoid deadlock entirely.

What a naïve implementation might do is simply lock lck1, and then lck2. If another thread simply locks lck2, and then locks lck1, you've got a potential deadlock. That's the scenario std::lock is designed to prevent. It will block if the locks cannot be acquired, but if one lock cannot be acquired, it won't hold any other lock.