问题
std::lock is used to prevent deadlock, right? However in my testing, it still caused deadlock. Could you check my test code to see if I used it incorrectly?
std::mutex m1;
std::mutex m2;
void func1()
{
std::unique_lock<std::mutex> lock1(m1, std::defer_lock);
printf("func1 lock m1\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
std::unique_lock<std::mutex> lock2(m2, std::defer_lock);
printf("func1 lock m2\n");
std::lock(m1, m2);
printf("func1 std lock\n");
}
void func2()
{
std::unique_lock<std::mutex> lock1(m2, std::defer_lock);
printf("func2 lock m2\n");
std::this_thread::sleep_for(std::chrono::seconds(2));
std::unique_lock<std::mutex> lock2(m1, std::defer_lock);
printf("func2 lock m1\n");
std::lock(m2, m1);
printf("func2 std lock\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
std::thread th1(func1);
std::thread th2(func2);
th1.join();
th2.join();
return 0;
}
The output is : func1 lock m1 func2 lock m2 func2 lock m1 func1 lock m2 func2 std lock
Then console hung...
回答1:
I think what you're trying to do doesn't work: You cannot silently modify the mutex underneath the unique lock. According to the specification, the "deferred" constructor makes the lock guard "not owning", and you cannot change that:
unique_lock(mutex_type& m, defer_lock_t) noexcept;
Effects: Constructs an object of type
unique_lock
.Postconditions:
pm == addressof(m)
andowns == false
.
The only way to modify the exposition-only owns
variable is by acting on the unique lock. The unique lock does not magically inspect the state of the held mutex.
The correct code should pass the unique lock to the std::lock
algorithm:
std::lock(lock1, lock2);
来源:https://stackoverflow.com/questions/45821512/stdlock-still-caused-deadlock