简体   繁体   中英

How to use the non-member function lock

#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?

Here

lock(lck1,lck2);
t1.join();

you lock mutex m1 and then waits for t1 to complete.

In t1 you also lock m1 - here

m1.lock();

If lock(lck1,lck2); succeeds before m1.lock(); you have a deadlock as t1 will never complete because main has a lock on m1

If m1.lock(); succeeds before lock(lck1,lck2); the program will execute fine.

However, you can't know which lock succeeds.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM